Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek vysvětluje, jak systém migrací v Django funguje se serverem SQL Server prostřednictvím backendu mssql-django, a dokumentuje známé okrajové případy.
Vytvoření a použití migrací
Pracovní postup migrace Django funguje stejně s SQL Server jako s jinými databázemi:
Generování migrací ze změn modelu:
python manage.py makemigrations myappZkontrolujte vygenerované soubory migrace v souboru
<app>/migrations/.Aplikujte migrace na databázi:
python manage.py migrate myappKontrola stavu migrace:
python manage.py showmigrations myapp
Počáteční nastavení projektu
Když nastavíte nový projekt Django s SQL Server, spusťte migrace a vytvořte předdefinované tabulky Django (ověřování, relace, správce):
python manage.py migrate
Tento příkaz vytvoří všechny tabulky vyžadované aplikacemi uvedenými v seznamu INSTALLED_APPS.
Vlastní SQL v migracích
Slouží migrations.RunSQL ke spouštění nezpracovaných příkazů SQL během migrací. Tento přístup je užitečný při vytváření uložených procedur, triggerů nebo jiných objektů specifických pro SQL Server:
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;",
),
]
Známé okrajové případy při migraci
Následující operace migrace vyžadují alternativní řešení při cílení na SQL Server.
Změna AutoField
Změna pole modelu z nebo do AutoField okamžiku migrace se nepodporuje. SQL Server nepovoluje přidání nebo odebrání IDENTITY vlastnosti z existujícího sloupce.
Alternativní řešení: Vytvoření nového modelu s požadovaným typem pole Migrujte data ze staré tabulky do nové tabulky a potom zahoďte starou tabulku.
Přejmenovat pole nebo model s omezeními cizího klíče
Přejmenování pole nebo modelu s omezeními cizího klíče může selhat. SQL Server během operací přejmenování vyžaduje vyřazení a opětovné vytvoření omezení FK.
Alternativní řešení: Slouží migrations.SeparateDatabaseAndState k vyřazení omezení FK, přejmenování sloupce a opětovnému vytvoření omezení a zobrazení upozornění Django, aby aktualizoval stav modelu. Následující příklad přejmenuje cizí klíč product u modelu Order na 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",
),
],
),
]
Před spuštěním tohoto kódu T-SQL vyhledejte ve své databázi skutečný název omezení. Django generuje názvy omezení obsahující krátký hash, takže název ve vašem schématu neodpovídá zástupnému symbolu uvedenému zde.
Migrace squashů
Po mnoha migracích je můžete zmáčknout do menšího počtu souborů:
python manage.py squashmigrations myapp 0001 0010
Tip
Vždy otestujte chycené migrace proti nové databázi, abyste měli jistotu, že vytvoří správné schéma.
Generované sloupce (počítané sloupce)
Backend mssql-django podporuje funkci Django GeneratedField (Django 5.0 a novější), která odpovídá vypočítaným sloupcům v SQL Serveru.
Uložené (PERSISTED) generované sloupce
Uložený vygenerovaný sloupec se fyzicky zapisuje na disk a aktualizuje se při změně zdrojových sloupců:
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,
)
Tím se vygeneruje: total_price AS ([price] * (1 + [tax_rate])) PERSISTED.
Virtuální generované sloupce
Virtuální generovaný sloupec se vypočítává při dotazu a nezabírá úložný prostor:
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
SQL Server omezuje vytváření indexů na nepersistovaných vypočítaných sloupcích. Použijte db_persist=True , pokud potřebujete indexovat vygenerovaný sloupec.
Komentáře k tabulce a sloupcům
Backend mssql-django podporuje funkci db_comment frameworku Django (Django 4.2 a novější). Komentáře jsou uloženy jako MS_Description rozšířené vlastnosti v objektu SQL Server.
Komentáře k tabulce
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."
Komentáře ke sloupcům
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")
Komentáře jsou viditelné v SQL Server Management Studio ve vlastnostech sloupce nebo tabulky a prostřednictvím sys.extended_properties.
Složené primární klíče
Django 5.2 představil CompositePrimaryKey. Back-end mssql-django má částečnou podporu složených primárních klíčů, ale některé testovací případy Django jsou stále vyloučené. Před nasazením do produkčního prostředí ověřte ve své aplikaci migrace a dotazy používající složené klíče.
-
inspectdbnegeneruje správně složené primární klíče. Definujte je ručně po kontrole. - Vyhledávání ntic nejsou podporována. Backend rozkládá porovnání složených klíčů na podmínky jednotlivých sloupců.
- Porovnání n-tic s poddotazy vyžaduje Django 5.2.4 a novější.
- Některé operace migrace mají stále známá vyloučení. Aktuální stav najdete v tématu Omezení a nepodporované funkce v mssql-django .
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 Zpracování
Když vložíte explicitní hodnoty do AutoField (například při obnově dat ze zálohy s konkrétními ID), backend automaticky obalí příkaz INSERT do SET IDENTITY_INSERT ON / SET IDENTITY_INSERT OFF. Není potřeba žádný ruční SQL.
# The backend handles IDENTITY_INSERT automatically
Product.objects.create(id=42, name="Restored Widget", price=9.99)
Note
SQL Server umožňuje, aby v rámci jedné relace měla IDENTITY_INSERT ON současně jen jedna tabulka. Pokud v jednom bloku atomic() vložíte explicitní ID do více tabulek, backend zpracovává toto přepnutí pro každý příkaz zvlášť. Avšak souběžné relace, které také používají IDENTITY_INSERT nad stejnou tabulkou, mohou být v konfliktu.