Conas imirce bunachar sonraí a chruthúLink to this heading
Míníonn an doiciméad seo conas imirce bunachar sonraí a struchtúrú agus a scríobh do chásanna éagsúla a d'fhéad Le haghaidh ábhar tosaigh maidir le himirce, féach:doc: `an treoir ábhair `</topics/migrations>.
Imirce sonraí agus bunachair sonraí iolrachaLink to this heading
Agus bunachair sonraí iolracha á úsáid agat, b'fhéidir go mbeidh ort a fháil amach cibé acu imirce a reáchtáil i gcoinne bunachar sonraí áirithe nó Mar shampla, b'fhéidir gur mhaith leat imirce a reáchtáil** ar bhunachar sonraí áirithe.
D'fhonn é sin a dhéanamh is féidir leat ainm an nasc bunachar sonraí a sheiceáil taobh istigh d'oibríocht RunPython trí fhéachaint ar an tréith schema_editor.connection.alias`:
from django.db import migrations
def forwards(apps, schema_editor):
if schema_editor.connection.alias != "default":
return
# Your migration code goes here
class Migration(migrations.Migration):
dependencies = [
# Dependencies to other migrations
]
operations = [
migrations.RunPython(forwards),
]
Is féidir leat leideanna a sholáthar freisin a chuirfear ar aghaidh chuig an modh:meth: allow_migration () `de ródairí bunachar sonraí mar `**hints`:
myapp/dbrouters.pyclass MyRouter:
def allow_migrate(self, db, app_label, model_name=None, **hints):
if "target_db" in hints:
return db == hints["target_db"]
return True
Ansin, chun é seo a ghiaráil i do imirce, déan an méid seo a leanas:
from django.db import migrations
def forwards(apps, schema_editor):
# Your migration code goes here
...
class Migration(migrations.Migration):
dependencies = [
# Dependencies to other migrations
]
operations = [
migrations.RunPython(forwards, hints={"target_db": "default"}),
]
Mura ndéanann d'oibríocht `` RunPython`` nó `` RunSQL`` difear ach do mhúnla amháin, is dea-chleachtas é `` model_name`` a chur ar aghaidh mar leid chun é a dhéanamh chomh trédhearcach agus is féidir don ródaire. Tá sé seo tábhachtach go háirithe maidir le haipeanna ath-inúsáidte agus tríú páirtí.
Imirce a chuireann réimsí uathúla leisLink to this heading
Má chuirtear ascnamh “gnáth” i bhfeidhm a chuireann réimse uathúil neamh-neamhnithe le tábla le sraitheanna atá ann cheana féin, ardófar earráid mar ní ghintear an luach a úsáidtear chun sraitheanna atá ann cheana a líonadh ach uair amháin, rud a bhriseann an srian uathúil.
Dá bhrí sin, ba chóir na céimeanna seo a leanas a dhéanamh. Sa sampla seo, cuirfimid neamh-nullable:class: ~django.db.models.uuidfield le luach réamhshocraithe. Athraigh an réimse faoi seach de réir do riachtanas.
Cuir an réimse ar do mhúnla le default=uuid.uuid4` agus
Unique=Trueargóintí (roghnaigh réamhshocrú cuí don chineál réimse atá á chur leis).Rith an t-ordú:djadmin: makemigrations. Ba chóir go gcruthódh sé seo imirce le hoibríocht AddField.
Ginigh dhá chomhad imirce folamh don aip céanna trí makemigrations myapp --empty a reáchtáil faoi dhó. Rinneamar athainmniú na comhaid imirce chun ainmneacha bríocha a thabhairt dóibh sna samplaí thíos.
Cóipeáil an oibríocht AddField ón imirce uathoibríoch a ghintear (an chéad cheann de na trí chomhad nua) go dtí an imirce deireanach, athraigh
Addfieldgo AlterField, agus cuir allmhairí uuid` agus samhlacha `. Mar shampla:0006_remove_uuid_null.py# Generated by Django A.B on YYYY-MM-DD HH:MM from django.db import migrations, models import uuid class Migration(migrations.Migration): dependencies = [ ("myapp", "0005_populate_uuid_values"), ] operations = [ migrations.AlterField( model_name="mymodel", name="uuid", field=models.UUIDField(default=uuid.uuid4, unique=True), ), ]Cuir an chéad chomhad imirce in eagar. Ba chóir go mbeadh cuma cosúil leis seo ar an rang imirce ginte:
0004_add_uuid_field.pyclass Migration(migrations.Migration): dependencies = [ ("myapp", "0003_auto_20150129_1705"), ] operations = [ migrations.AddField( model_name="mymodel", name="uuid", field=models.UUIDField(default=uuid.uuid4, unique=True), ), ]Athraigh
unique=TruegoNull=True- cruthóidh sé seo an réimse null idirghabhálaí agus cuirfidh sé siar an srian uathúil a chruthú go dtí go mbeidh luachanna uathúla curtha againn ar na sraitheanna go léir.Sa chéad chomhad imirce folamh, cuir a:class: ~django.db.migrations.operations.runpython nó:class: ~django.db.migrations.operations.runsql oibríocht chun luach uathúil (UUID sa sampla) a ghiniúint do gach sraith atá ann cheana. Cuir allmhairiú ``uuid ``leis freisin. Mar shampla:
0005_populate_uuid_values.py# Generated by Django A.B on YYYY-MM-DD HH:MM from django.db import migrations import uuid def gen_uuid(apps, schema_editor): MyModel = apps.get_model("myapp", "MyModel") for row in MyModel.objects.all(): row.uuid = uuid.uuid4() row.save(update_fields=["uuid"]) class Migration(migrations.Migration): dependencies = [ ("myapp", "0004_add_uuid_field"), ] operations = [ # omit reverse_code=... if you don't want the migration to be reversible. migrations.RunPython(gen_uuid, reverse_code=migrations.RunPython.noop), ]Anois is féidir leat na himirce a chur i bhfeidhm mar is gnách leis an ordú:djadmin: migrate.
Tabhair faoi deara go bhfuil coinníoll rása ann má cheadaíonn tú rudaí a chruthú agus an imirce seo á rith. Beidh a “uuid” bunaidh forscríofa ag rudaí a cruthaíodh tar éis an
Addfieldagus roimhRunpython.
Imirce neamh-adamhachaLink to this heading
Ar bhunachair sonraí a thacaíonn le hidirbhearta DDL (SQLite agus PostgreSQL), rithfidh imirce taobh istigh d'idirbheart de réir réamhshocraithe. Maidir le cásanna úsáide mar imirce sonraí a dhéanamh ar tháblaí móra, b'fhéidir gur mhaith leat imirce a chosc ó rith in idirbheart tríd an tréith atomic` a shocrú do `False:
from django.db import migrations
class Migration(migrations.Migration):
atomic = False
Laistigh d'imirce den sórt sin, reáchtáiltear gach oibríocht gan idirbheart. Is féidir codanna den imirce a fhorghníomhú taobh istigh d'idirbheart ag baint úsáid:func: ~django.db.transaction.atomic () `nó trí `Atomic=True` a chur chuig RunPython`.
Seo sampla d'imirce sonraí neamh-adamhacha a nuashonraíonn tábla mór i mbaisceanna níos lú:
import uuid
from django.db import migrations, transaction
def gen_uuid(apps, schema_editor):
MyModel = apps.get_model("myapp", "MyModel")
while MyModel.objects.filter(uuid__isnull=True).exists():
with transaction.atomic():
for row in MyModel.objects.filter(uuid__isnull=True)[:1000]:
row.uuid = uuid.uuid4()
row.save()
class Migration(migrations.Migration):
atomic = False
operations = [
migrations.RunPython(gen_uuid),
]
Níl éifeacht ag an tréith atomic ar bhunachair sonraí nach dtacaíonn le hidirbhearta DDL (m.sh. MySQL, Oracle). (Tagraíonn “tacaíocht ráiteas DDL adamhach” MySQL < https://dev.mysql.com/doc/refman/en/atomic-ddl.html> do ráitis aonair seachas ráitis iolracha atá fillte in idirbheart is féidir a rolladh ar ais.)
Ord na n-imirce a rialúLink to this heading
Cinneann Django an t-ord ina gcaithfear imirce a chur i bhfeidhm ní trí ainm comhaid gach imirce, ach trí graf a thógáil ag baint úsáide as dhá airíonna ar an aicme Imigration: dependencies` agus ``run_before ``.
Má d'úsáid tú an t-ordú:djadmin: makemigrations is dócha go bhfaca tú dependencies i ngníomh cheana féin toisc go bhfuil sé seo sainmhínithe ag imirce uathoibríoch mar chuid dá bpróiseas cruthaithe.
Dearbhaítear an maoin `spleáchais ``mar seo:
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("myapp", "0123_the_previous_migration"),
]
De ghnáth beidh sé seo go leor, ach ó am go ham b'fhéidir go gcaithfidh tú a chinntiú go ritheann d'imirce* roim* imirce eile. Tá sé seo úsáideach, mar shampla, chun imirce feidhmchláir tríú páirtí a reáchtáil* tar éis d'athsholáthar your:setting: AUTH_USER_MODEL.
Chun é seo a bhaint amach, cuir na himirce go léir ar chóir a bheith ag brath ar leatsa sa tréith run_before ``ar do rang ``Immigration:
class Migration(migrations.Migration):
...
run_before = [
("third_party_app", "0001_do_awesome"),
]
Is fearr leat dependencies a úsáid seachas run_before ``nuair is féidir. Níor cheart duit ``run_before ``a úsáid ach mura bhfuil sé inmhianaithe nó neamhphraiticiúil ``spleáchais a shonrú san imirce a theastaíonn uait a reáchtáil tar éis an ceann atá á scríobh agat.
Sonraí a imirce idir apps tríú páirtíLink to this heading
Is féidir leat imirce sonraí a úsáid chun sonraí a aistriú ó fheidhmchlár tríú páirtí amháin go ceann eile.
Má tá sé ar intinn agat an sean-aip a bhaint níos déanaí, beidh ort an maoin spleáchais ``a shocrú bunaithe ar cibé an bhfuil an sean-aip suiteáilte nó nach bhfuil. Seachas sin, beidh spleáchais in easnamh agat nuair a dhíshuiteálann tú an sean-aip. Ar an gcaoi chéanna, beidh ort: exc: `LookuPerror a ghabháil sa ghlao ``apps.get_model () ``a aisghabhann samhlacha ón sean-aip. Ligeann an cur chuige seo duit do thionscadal a imscaradh áit ar bith gan an sean-aip a shuiteáil agus ansin a dhíshuiteáil.
Seo imirce samplach:
myapp/imirceach/0124_move_old_app_to_new_app.pyfrom django.apps import apps as global_apps
from django.db import migrations
def forwards(apps, schema_editor):
try:
OldModel = apps.get_model("old_app", "OldModel")
except LookupError:
# The old app isn't installed.
return
NewModel = apps.get_model("new_app", "NewModel")
NewModel.objects.bulk_create(
NewModel(new_attribute=old_object.old_attribute)
for old_object in OldModel.objects.all()
)
class Migration(migrations.Migration):
operations = [
migrations.RunPython(forwards, migrations.RunPython.noop),
]
dependencies = [
("myapp", "0123_the_previous_migration"),
("new_app", "0001_initial"),
]
if global_apps.is_installed("old_app"):
dependencies.append(("old_app", "0001_initial"))
Smaoinigh freisin ar cad ba mhaith leat a tharlóidh nuair nach gcuirtear an imirce i bhfeidhm. D'fhéadfá aon rud a dhéanamh (mar atá sa sampla thuas) nó cuid de na sonraí nó go léir a bhaint as an bhfeidhmchlár nua. Coigeartaigh an dara argóint den oibríocht: mod: ~django.db.migrations.operations.runpython dá réir.
Athrú `ManyTomanyField chun samhail ``trí ``a úsáidLink to this heading
If you change a ManyToManyField to use a through
model, the default migration will delete the existing table and create a new
one, losing the existing relations. To avoid this, you can use
SeparateDatabaseAndState to rename the existing table to the new
table name while telling the migration autodetector that the new model has
been created. You can check the existing table name and constraint name through
sqlmigrate or dbshell. You can check the new table name
with the through model's _meta.db_table property. Your new through
model should use the same names for the ForeignKeys as Django did. Also if
it needs any extra fields, they should be added in operations after
SeparateDatabaseAndState.
Mar shampla, dá mbeadh samhail Leabhar againn le ManyTomanyField ag nascadh le Author ``, d'fhéadfaimis samhail tríd ``Authorbook a chur leis le réimse nua is_primary, mar shampla:
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("core", "0001_initial"),
]
operations = [
migrations.SeparateDatabaseAndState(
database_operations=[
# Old table name from checking with sqlmigrate, new table
# name from AuthorBook._meta.db_table.
migrations.RunSQL(
sql="ALTER TABLE core_book_authors RENAME TO core_authorbook",
reverse_sql="ALTER TABLE core_authorbook RENAME TO core_book_authors",
),
],
state_operations=[
migrations.CreateModel(
name="AuthorBook",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"author",
models.ForeignKey(
on_delete=django.db.models.deletion.DO_NOTHING,
to="core.Author",
),
),
(
"book",
models.ForeignKey(
on_delete=django.db.models.deletion.DO_NOTHING,
to="core.Book",
),
),
],
options={
"constraints": [
models.UniqueConstraint(
fields=["author", "book"],
name="unique_author_book",
)
],
},
),
migrations.AlterField(
model_name="book",
name="authors",
field=models.ManyToManyField(
to="core.Author",
through="core.AuthorBook",
),
),
],
),
migrations.AddField(
model_name="authorbook",
name="is_primary",
field=models.BooleanField(default=False),
),
]
Samhail neamh-bhainistithe a athrú go bainistitheLink to this heading
Más mian leat samhail neamhbhainistithe (:attr: managed=false <django.db.models.Options.managed>) a athrú go bainistithe, ní mór duit Managed = False` a bhaint agus imirce a ghiniúint sula ndéanann tú athruithe eile a bhaineann le scéim ar an tsamhail, ós rud é nach féidir athruithe scéime atá le feiceáil san imirce ina bhfuil an oibríocht chun `Meta.Managed ``a athrú.