Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este artigo explica como o sistema de migração do Django funciona com SQL Server por meio do mssql-django back-end e documenta casos de borda conhecidos.
Criar e aplicar migrações
O fluxo de trabalho de migração do Django funciona da mesma maneira com SQL Server que com outros bancos de dados:
Gerar migrações a partir de alterações no modelo:
python manage.py makemigrations myappExamine os arquivos de migração gerados em
<app>/migrations/.Aplicar migrações ao banco de dados:
python manage.py migrate myappVerifique o status da migração:
python manage.py showmigrations myapp
Configuração inicial do projeto
Ao configurar um novo projeto do Django com SQL Server, execute migrações para criar tabelas internas do Django (autenticação, sessões, administrador):
python manage.py migrate
Esse comando cria todas as tabelas exigidas por aplicativos listados em INSTALLED_APPS.
SQL personalizado em migrações
Use migrations.RunSQL para executar instruções SQL brutas durante as migrações. Essa abordagem é útil para criar procedimentos armazenados, gatilhos ou outros objetos específicos 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;",
),
]
Casos de borda de migração conhecidos
As operações de migração a seguir exigem soluções alternativas ao ter o SQL Server como destino.
Alteração do AutoField
Não há suporte para alterar um campo do modelo de ou para AutoField no momento da migração. SQL Server não permite adicionar ou remover a IDENTITY propriedade de uma coluna existente.
Solução alternativa: crie um novo modelo com o tipo de campo desejado. Migre dados da tabela antiga para a nova tabela e solte a tabela antiga.
Renomear campo ou modelo com restrições de chave estrangeira
A renomeação de um campo ou modelo que tenha restrições de chave estrangeira pode falhar. SQL Server requer a remoção e recriação de restrições de FK durante operações de renomeação.
Solução alternativa: use migrations.SeparateDatabaseAndState para remover a restrição FK, renomear a coluna e recriar a restrição, informando ao Django que atualize o estado do modelo. O exemplo a seguir renomeia a product chave estrangeira em um Order modelo para 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",
),
],
),
]
Procure o nome da restrição real em seu banco de dados antes de executar esse código T-SQL. O Django gera nomes de restrição que incluem um hash curto, portanto, o nome em seu esquema não corresponde ao espaço reservado mostrado aqui.
Migrações de squash
Depois que muitas migrações se acumularem, você poderá esmagá-las em menos arquivos:
python manage.py squashmigrations myapp 0001 0010
Tip
Sempre teste migrações esmagadas em um novo banco de dados para garantir que elas produzam o esquema correto.
Colunas geradas (colunas computadas)
O mssql-django backend oferece suporte a GeneratedField do Django (Django 5.0 e posteriores), que corresponde a colunas computadas do SQL Server.
Colunas armazenadas (PERSISTED) geradas
Uma coluna gerada armazenada é gravada fisicamente no disco e atualizada quando as colunas de origem são alteradas:
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,
)
Isso gera: total_price AS ([price] * (1 + [tax_rate])) PERSISTED.
Colunas geradas virtualmente
Uma coluna gerada virtual é computada no momento da consulta e não consome armazenamento:
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 restringe índices em colunas computadas não persistentes. Use db_persist=True se precisar indexar a coluna gerada.
Comentários de colunas e tabelas
O mssql-django backend oferece suporte ao recurso db_comment do Django (Django 4.2 e posteriores). Os comentários são armazenados como MS_Description propriedades estendidas no objeto SQL Server.
Comentários sobre a tabela
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."
Comentários de coluna
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")
Os comentários são visíveis em SQL Server Management Studio em propriedades de coluna/tabela e via sys.extended_properties.
Chaves primárias compostas
O Django 5.2 introduziu CompositePrimaryKey. O mssql-django back-end tem suporte parcial para chaves primárias compostas, mas alguns casos de teste do Django ainda são excluídos. Valide as migrações e consultas de chave composta em seu aplicativo antes de adotá-las em produção.
-
inspectdbnão gera chaves primárias compostas corretamente. Defina-os manualmente após a inspeção. - Não há suporte para consultas de tupla. O backend decompõe comparações de chaves compostas em condições individuais por coluna.
- A comparação de tuplas com subconsultas requer o Django 5.2.4 ou posterior.
- Algumas operações de migração ainda têm exclusões conhecidas. Consulte Limitações e recursos sem suporte no mssql-django para obter o status atual.
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 tratamento
Quando você insere valores explícitos em um AutoField (por exemplo, restaurando dados de um backup com IDs específicas), o back-end encapsula automaticamente a inserção.SET IDENTITY_INSERT ON / SET IDENTITY_INSERT OFF Nenhum SQL manual é necessário.
# The backend handles IDENTITY_INSERT automatically
Product.objects.create(id=42, name="Restored Widget", price=9.99)
Note
SQL Server permite que apenas uma tabela por sessão tenha IDENTITY_INSERT ON de cada vez. Se você inserir IDs explícitos em várias tabelas em um único bloco atomic(), o backend controla a alternância por instrução. No entanto, sessões simultâneas que também usam IDENTITY_INSERT na mesma tabela podem entrar em conflito.