Хостинг Django от «Джино»
Содержимое

Внесение изменений в схему базы данных

Когда мы описывали команду syncdb в этой главе, мы отметили, что эта команда создаёт только те таблицы, которых ещё нет в базе данных. Она не синхронизирует изменения в моделях и не выполняет удаление моделей. Если вы изменили или добавили поле в модель, или если вы удалили модель, вам потребуется вручную внести эти изменения в базу данных. Этот раздел объяснит как это сделать.

При работе с изменениями схемы следует помнить особенности работы Django API для доступа к базе данных:

  • Django будет сильно ругаться, если модель содержит поле, которое ещё не было создано в таблице базы данных. Это приведёт к ошибке при первом обращении к этой таблице (т.е., ошибка произойдёт во время выполнения, не во время компиляции).

  • Django не беспокоится о том, что таблица может содержать столбцы, которые не определены в модели.

  • Django не беспокоится о том, что база данных может содержать таблицу, которая не представлена в виде модели.

Внесение изменений в схему означает изменение нескольких частей проекта — сначала в коде, а потом в самой базе данных.

Добавление полей

При добавлении поля в таблицу/модель работающего сайта следует воспользоваться тем моментом, что Django не обращает внимание на поле таблицы, пока оно не определено в модели. Следовательно, стратегия такая — добавляем поле в таблицу, затем вносим изменения в модель.

Тем не менее, здесь существует проблема курицы и яйца, так как, чтобы узнать как должен выглядеть оператор для добавления поля, вам потребуется посмотреть на вывод команды manage.py sqlall, которая требует наличия этого поля в модели. (Следует отметить, что нет требования создавать поле с помощью предлагаемого Django SQL кода, но по-хорошему это было бы правильно.)

Решением проблемы курицы и яйца является использование отдельной среды разработки, вместо внесения изменений в код работающего сервера. (Надеемся, вы используете отдельную среду разработки, так?)

Сначала, выполните это в среде разработки (т.е., не на рабочем сервере):

  1. Добавьте поле в вашу модель.

  2. Запустите команду manage.py sqlall [ИМЯ_ПРИЛОЖЕНИЯ], чтобы посмотреть новый оператор CREATE TABLE для модели. Следует посмотреть на определение нового поля.

  3. Запустите оболочку клиента базы данных (т.е., psql или mysql или вы можете использовать manage.py dbshell). Выполните оператор ALTER TABLE для добавления нового поля.

  4. (Необязательный.) Запустите оболочку Python с помощью команды manage.py shell и проверьте, что новое поле добавлено правильно, т.е., импортируйте модель и произведите выборку из таблицы (например, MyModel.objects.all()[:5]).

Затем выполните на рабочем сервере следующие шаги:

  1. Запустите оболочку базы данных.

  2. Выполните оператор ALTER TABLE, который вы использовали в шаге 3 при работе с тестовым сервером.

  3. Добавьте поле в вашу модель. Если вы используете систему контроля версий и сохранили в ней изменения в коде, сделанные в шаге 1 при работе с тестовым сервером, пришло время внести эти изменения в код, выполняющийся на боевом сервере (например, svn update).

  4. Перезапустите веб-сервер для активации изменений.

Для примера рассмотрим, что произойдёт если мы добавим поле num_pages к модели Book, описанной ранее в этой главе. Сначала мы должны внести изменения в модель тестового сервера:

class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher)
    publication_date = models.DateField()
    num_pages = models.IntegerField(blank=True, null=True)
    def __unicode__(self):
        return self.title

Следует отметить, что параметры blank=True и null=True разрешают выборку NOT NULL значений из поля num_pages.

Затем мы выполнили manage.py sqlall books, чтобы посмотреть на оператор CREATE TABLE:

CREATE TABLE "books_book" (
    "id" serial NOT NULL PRIMARY KEY,
    "title" varchar(100) NOT NULL,
    "publisher_id" integer NOT NULL REFERENCES "books_publisher" ("id"),
    "publication_date" date NOT NULL,
    "num_pages" integer NULL
);

Новое поле представлено как:

"num_pages" integer NULL

Затем, мы запустили оболочку базы данных на рабочем сервере, набрав psql (для PostgreSQL) и выполнили следующий оператор:

ALTER TABLE books_book ADD COLUMN num_pages integer;

Добавление NOT NULL полей

Существует одна тонкость, которую следует упомянуть. При добавлении поля num_pages в модель мы указали параметры blank=True и null=True. Мы сделали это, потому что это поле будет содержать NULL значения при своём создании.

Однако, также есть возможность добавлять поля, которые не могут содержать NULL значения. Для этого вам потребуется создать поле, которое может содержать значения NULL, затем добавить несколько значений и после этого изменить тип поля на NOT NULL. Например:

BEGIN;
ALTER TABLE books_book ADD COLUMN num_pages integer;
UPDATE books_book SET num_pages=0;
ALTER TABLE books_book ALTER COLUMN num_pages SET NOT NULL;
COMMIT;

Если вы пойдёте по этому пути, запомните, что вы должны оставить параметры blank=True и null=True в вашей модели.

После выполнения оператора ALTER TABLE мы проверили, что изменения работают правильно, запустив оболочку Python и выполнив код:

>>> from mysite.books.models import Book
>>> Book.objects.all()[:5]

Если этот код выполнился без ошибок, мы переключаемся на рабочий сервер и выполняем оператор ALTER TABLE на рабочей базе данных. Затем, мы обновляем модель и перезапускаем веб-сервер.

Удаление полей

Удалять поля из модели гораздо проще, чем добавлять. Для удаления поля просто следуйте следующим шагам:

  1. Удалите поля из вашей модели и перезапустите веб-сервер.

  2. Удалите поле из таблицы с помощью команды:

    ALTER TABLE books_book DROP COLUMN num_pages;
    

Удаление полей со связями многие-ко-многим

Так как поля со связями «многие-ко-многим» отличаются от обычных полей, процесс их удаления немного отличается:

  1. Удалите поле ManyToManyField из модели и перезапустите веб-сервер.

  2. Удалите соответствующую таблицу из базы данных:

    DROP TABLE books_books_publishers;
    

Удаление моделей

Удаление модели в целом не сложнее удаления поля. Для того, чтобы удалить модель, просто следуйте этим шагам:

  1. Удалите модель из файла models.py и перезапустите веб-сервер.

  2. Удалите таблицу из базы данных с помощью команды:

    DROP TABLE books_book;
    

rad 3 недели, 6 дней прошло
Ответ Ссылка

Поздравляем, вы попали на секретный уровень сайта!

Nelly_lucky 3 недели, 6 дней прошло
Ответ Ссылка

Тоисть когда находишься на http://djbook.ru/ch05s12.html
и жмёшь След.
выдаёт
http://djbook.ru/ch06.html
но ни как не
http://djbook.ru/ch05s13.html

Nelly_lucky 3 недели, 6 дней прошло
Ответ Ссылка

Эту статтю не видно если просматривать через сылки, только через прописания конкретного url который я узнал случайно


SecureLayer: Передавай данные по защищённому каналу! Просто, быстро и бесплатно!

Ищем Python программистов

Нашли опечатку?
Выделите её мышкой и нажмите Enter
Ctrl-Enter
Выполнено:
30 1 199 25


Полный репозиторий перевода DjangoBook вы можете получить на GitHub.
Мы ждём ваших патчей!

Мы рады получить ваши вопросы, комментарии или предложения!
(Открыть новую вкладку)

Всего пользователей: 566

Русская группа

на поддержку перевода
Яндекс Яндекс.Деньги Хочу такую же кнопку
Ускорить процесс перевода!
ЯМ:41001223475816


© 2008-2012 Ruslan Popov @ gmail.com Powered by Django 1.2.5