Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ez a cikk bemutatja, hogyan működik a Django migrációs rendszere az SQL Servert kezelő mssql-django háttérrendszeren keresztül, és dokumentálja az ismert speciális eseteket.
Migrálások létrehozása és alkalmazása
A Django migrálási munkafolyamata ugyanúgy működik a SQL Server, mint más adatbázisokkal:
Migrálások létrehozása modellmódosításokból:
python manage.py makemigrations myappTekintse át a létrehozott migrációs fájlokat itt:
<app>/migrations/.Migrálás alkalmazása az adatbázisra:
python manage.py migrate myappA migrálás állapotának ellenőrzése:
python manage.py showmigrations myapp
Kezdeti projektbeállítás
Amikor új Django-projektet állít be SQL Server használatával, futtassa a migrációkat a Django beépített tábláinak (hitelesítés, munkamenetek, adminisztráció) létrehozásához:
python manage.py migrate
Ez a parancs létrehozza a listában felsorolt alkalmazásokhoz szükséges összes táblát INSTALLED_APPS.
Egyéni SQL a migrálásokban
A migrálás során nyers SQL-utasítások végrehajtására használható migrations.RunSQL . Ez a módszer tárolt eljárások, eseményindítók vagy más SQL Server-specifikus objektumok létrehozásához hasznos:
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("myapp", "0001_initial"),
]
operations = [
migrations.RunSQL(
sql="CREATE INDEX IX_myapp_product_name ON myapp_product (name);",
reverse_sql="DROP INDEX IX_myapp_product_name ON myapp_product;",
),
]
Ismert migrációs szélső esetek
Az alábbi migrálási műveletek kerülőmegoldásokat igényelnek, ha a cél az SQL Server.
Automatikus mező módosítása
A modellmezőnek a migrálás során AutoField típusról vagy típusra történő módosítása nem támogatott. SQL Server nem engedélyezi a IDENTITY tulajdonság hozzáadását vagy eltávolítását egy meglévő oszlopból.
Megkerülő megoldás: Hozzon létre egy új modellt a kívánt mezőtípussal. A régi táblából az új táblába migrálhatja az adatokat, majd elveti a régi táblát.
Mező vagy modell átnevezése idegenkulcs-korlátozásokkal
Az idegenkulcs-korlátozásokkal rendelkező mezők vagy modellek átnevezése sikertelen lehet. SQL Server FK-korlátozások elvetését és újrakonformálását igényli az átnevezési műveletek során.
Megkerülő megoldás: Az FK-kényszer elvetésére, az oszlop átnevezésére és a kényszer újbóli létrehozására használható migrations.SeparateDatabaseAndState , miközben a Django-t arra utasítja, hogy frissítse a modell állapotát. Az alábbi példa átnevezi a product modell idegen kulcsát Order a következőre item:
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("myapp", "0002_previous"),
]
operations = [
migrations.SeparateDatabaseAndState(
database_operations=[
migrations.RunSQL(
sql="ALTER TABLE myapp_order DROP CONSTRAINT FK_order_product;",
reverse_sql="ALTER TABLE myapp_order ADD CONSTRAINT FK_order_product FOREIGN KEY (product_id) REFERENCES myapp_product(id);",
),
migrations.RunSQL(
sql="EXECUTE sp_rename 'myapp_order.product_id', 'item_id', 'COLUMN';",
reverse_sql="EXECUTE sp_rename 'myapp_order.item_id', 'product_id', 'COLUMN';",
),
migrations.RunSQL(
sql="ALTER TABLE myapp_order ADD CONSTRAINT FK_order_item FOREIGN KEY (item_id) REFERENCES myapp_product(id);",
reverse_sql="ALTER TABLE myapp_order DROP CONSTRAINT FK_order_item;",
),
],
state_operations=[
migrations.RenameField(
model_name="order",
old_name="product",
new_name="item",
),
],
),
]
A T-SQL-kód futtatása előtt keresse meg az adatbázis tényleges kényszernevét. A Django rövid kivonatot tartalmazó kényszerneveket hoz létre, így a séma neve nem egyezik az itt látható helyőrzővel.
Migrációk összevonása
Miután sok migrálás halmozódott fel, kevesebb fájlba gyűjtheti őket:
python manage.py squashmigrations myapp 0001 0010
Tip
A tömörített migrációkat mindig tesztelje egy új adatbázison, annak biztosítására, hogy azok a megfelelő sémát eredményezzék.
Generált oszlopok (számított oszlopok)
A mssql-django backend támogatja a Django GeneratedField funkcióját (a Django 5.0-s és újabb verzióiban), amely az SQL Server számított oszlopainak felel meg.
Tárolt (TARTÓS) generált oszlopok
A tárolt generált oszlopok fizikailag a lemezre lesznek írva, és a forrásoszlopok változásakor frissülnek:
from django.db import models
from django.db.models import F
class Product(models.Model):
price = models.DecimalField(max_digits=10, decimal_places=2)
tax_rate = models.DecimalField(max_digits=5, decimal_places=4)
total_price = models.GeneratedField(
expression=F("price") * (1 + F("tax_rate")),
output_field=models.DecimalField(max_digits=10, decimal_places=2),
db_persist=True,
)
Ez a következőt hozza létre: total_price AS ([price] * (1 + [tax_rate])) PERSISTED.
Virtuálisan létrehozott oszlopok
A virtuálisan létrehozott oszlopokat a rendszer lekérdezéskor számítja ki, és nem használja fel a tárterületet:
from django.db import models
from django.db.models import F, Value
from django.db.models.functions import Concat
class Employee(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
full_name = models.GeneratedField(
expression=Concat(F("first_name"), Value(" "), F("last_name")),
output_field=models.CharField(max_length=101),
db_persist=False,
)
Note
Az SQL Server korlátozza az indexek létrehozását a nem perzisztált számított oszlopokon. Akkor használja db_persist=True , ha indexelnie kell a létrehozott oszlopot.
Táblázat- és oszlopbejegyzések
A mssql-django háttérrendszer támogatja a Django funkcióját db_comment (Django 4.2 és újabb verziók). A megjegyzések kiterjesztett tulajdonságokként MS_Description vannak tárolva az SQL Server objektumon.
Táblázat megjegyzései
class AuditLog(models.Model):
action = models.CharField(max_length=50)
timestamp = models.DateTimeField(auto_now_add=True)
class Meta:
db_table_comment = "Tracks user actions for compliance auditing."
Oszlop megjegyzései
class Measurement(models.Model):
value = models.FloatField(db_comment="Sensor reading in Celsius")
recorded_at = models.DateTimeField(db_comment="UTC timestamp from the data logger")
A megjegyzések SQL Server Management Studio oszlop-/táblatulajdonságok alatt és a területen sys.extended_propertiesláthatók.
Összetett elsődleges kulcsok
Django 5.2 bevezetett CompositePrimaryKey. A mssql-django háttérrendszer részlegesen támogatja az összetett elsődleges kulcsokat, de néhány Django-teszteset továbbra is ki van zárva. Ellenőrizze az összetett kulcsú migrálásokat és lekérdezéseket az alkalmazáson, mielőtt éles környezetben bevezeti őket.
-
inspectdbnem hozza létre megfelelően az összetett elsődleges kulcsokat. Az ellenőrzés után manuálisan definiálhatja őket. - A Tuple-keresések nem támogatottak. A háttérrendszer az összetett kulcsok összehasonlítását különálló oszlopfeltételekre bontja.
- A tuple-ök albekérdezésekkel való összehasonlításához a Django 5.2.4-es vagy újabb verziója szükséges.
- Egyes áttelepítési műveletek továbbra is ismert kizárásokkal rendelkeznek. Tekintse meg az mssql-django jelenlegi állapotának korlátozásait és nem támogatott funkcióit .
from django.db import models
from django.db.models import CompositePrimaryKey
class OrderItem(models.Model):
pk = CompositePrimaryKey("order_id", "product_id")
order = models.ForeignKey("Order", on_delete=models.CASCADE)
product = models.ForeignKey("Product", on_delete=models.CASCADE)
quantity = models.IntegerField()
IDENTITY_INSERT Kezelése
Amikor explicit értékeket szúr be egy AutoField fájlba (például egy adott azonosítóval rendelkező biztonsági másolat adatainak visszaállítása), a háttérrendszer automatikusan becsomagolja a beszúrást SET IDENTITY_INSERT ON / SET IDENTITY_INSERT OFF. Nincs szükség manuális SQL-re.
# The backend handles IDENTITY_INSERT automatically
Product.objects.create(id=42, name="Restored Widget", price=9.99)
Note
A SQL Server munkamenetenként egyszerre csak egy táblán engedélyezi a(z) IDENTITY_INSERT ON használatát. Ha explicit azonosítókat illeszt be több táblába egyetlen atomic() blokkban, a backend utasításonként kezeli az átváltást. Az ugyanazon a táblán is használt IDENTITY_INSERT egyidejű munkamenetek azonban ütközhetnek.