Django Model Modification and data migration, django model migration
Migrations
It is troublesome for Django to modify the Model. The syncdb command only creates tables that are not in the database and does not modify existing data tables synchronously, you cannot delete the data model. If you add or modify fields in the data model or delete a data model, you need to manually modify the fields in the database or use South. Django 1.7 has integrated the South code and provided three new commands:
- Migrate: used to execute migration actions, with the syncdb Function
- Makemigrations: Creates a new migration policy file based on the current model.
- Sqlmigrate: displays the SQL statement for migration, with the sqlall Function
It is easy to use. After modifying the Model, use makemigrations to record the modification:
$ python manage.py makemigrationsMigrations for 'books': 0003_auto.py: - Alter field author on book
Your Model will be scanned, compared with the previous versions in the migrations folder, and then generate the migration file.
With the new migration file, you can use migrate to modify the database mode:
$ python manage.py migrateOperations to perform: Synchronize unmigrated apps: sessions, admin, messages, auth, staticfiles, contenttypes Apply all migrations: booksSynchronizing apps without migrations: Creating tables... Installing custom SQL... Installing indexes...Installed 0 object(s) from 0 fixture(s)Running migrations: Applying books.0003_auto... OK
You can also generate migration for a separate app:
$ python manage.py makemigrations your_app_label
You can also modify the data in the database. First, create an empty migration file:
python manage.py makemigrations --empty yourappname
The file content is as follows:
# -*- coding: utf-8 -*-from django.db import models, migrationsclass Migration(migrations.Migration): dependencies = [ ('yourappname', '0001_initial'), ] operations = [ ]
If you want to modify the data of a Model such as Person, set its name field:
# -*- coding: utf-8 -*-from django.db import models, migrationsdef combine_names(apps, schema_editor): # We can't import the Person model directly as it may be a newer # version than this migration expects. We use the historical version. Person = apps.get_model("yourappname", "Person") for person in Person.objects.all(): person.name = "%s %s" % (person.first_name, person.last_name) person.save()class Migration(migrations.Migration): dependencies = [ ('yourappname', '0001_initial'), ] operations = [ migrations.RunPython(combine_names), ]
Finally, run python manage. py migrate.You can. In this way, the name field of all objects in Person is set.
Modifying a relational database based on the Model is an important issue in development. Solving this problem can speed up development, but it is still very dangerous to use migrate to operate the database in the production environment, sometimes you need to manually modify the database.
Manually modify Database
When processing model modifications:
- If the model contains a field that has not been created in the database, Django reports an error. When you use Django's database API to request fields that do not exist in the table for the first time, an error occurs.
- Django does not care whether there are columns not defined in the model in the database table.
- Django does not care whether tables in the database are not represented by the model.
Add Field
Add fields to your model. The following example adds the num_pages field to the Book Model:
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
Run manage. py sqlall yourappname to test the new create table statement of the model.
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);
Enable the interactive command interface of your database (for example, psql or mysql, or you can use manage. py dbshell. Execute the alter table statement to add a new column.
ALTER TABLE books_book ADD COLUMN num_pages integer;
Add a non-NULL field
Create a NULL field, fill the value of the field with a default value, and then change the field to 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;
Add ForeignKey or ManyToManyField
Adding a foreign key is the integer field for adding key_id. Adding multiple-to-many fields is to create a new data table.
Delete Field
It is relatively simple. Just delete a column in the table.
ALTER TABLE books_book DROP COLUMN num_pages;
Sqlite3 may be difficult to use. sqlite3 does not support column deletion and only supports alter table. You can use it to add a column at the end of the table to change the table name. To make more complex changes to the table structure, you must create a new table. You can put existing data in a temporary table, delete the original table, create a new table, and copy the data from the temporary table.
For example, assume that there is a t1 table with three columns: "a", "B", and "c". If you want to delete column c:
BEGIN TRANSACTION;CREATE TEMPORARY TABLE t1_backup(a,b);INSERT INTO t1_backup SELECT a,b FROM t1;DROP TABLE t1;CREATE TABLE t1(a,b);INSERT INTO t1 SELECT a,b FROM t1_backup;DROP TABLE t1_backup;COMMIT;
Delete multiple-to-multiple association fields
Delete multiple-to-multiple join data tables.
DROP TABLE books_book_authors;
Delete Model
Delete A data table.
DROP TABLE books_book;
Data Migration
The django project provides an export Method for python manage. py dumpdata. If no appname is specified, all apps are exported by default.
python manage.py dumpdata myapp > myapp.json
Format of exported file content:
[ { "model": "myapp.person", "pk": 1, "fields": { "first_name": "John", "last_name": "Lennon" } }, { "model": "myapp.person", "pk": 2, "fields": { "first_name": "Paul", "last_name": "McCartney" } }]
Data Import:
python manage.py loaddata myapp.json
Export user data:
python manage.py dumpdata auth > auth.json