Faça engenharia reversa de modelos com inspectdb

Este artigo explica como usar o comando de gerenciamento do inspectdb Django para gerar código de modelo de um banco de dados SQL Server existente.

Pré-requisitos

Adicione mssql ao seu INSTALLED_APPS em settings.py. Esta etapa registra a substituição do comando de gerenciamento mssql-django para inspectdb, que adiciona a opção --schema para inspecionar esquemas não padrão:

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "mssql",
    "myapp",
]

Note

O mssql back-end do banco de dados funciona sem essa etapa. Adicionar "mssql" a INSTALLED_APPS só é necessário para habilitar o sinalizador --schema em inspectdb. Sem ele, inspectdb inspeciona apenas o esquema padrão (dbo).

Uso Básico

Gere modelos para todas as tabelas no banco de dados configurado:

python manage.py inspectdb

Salve a saída diretamente em um arquivo de modelos:

python manage.py inspectdb > myapp/models.py

Inspecionar tabelas específicas

Gere modelos apenas para tabelas específicas:

python manage.py inspectdb MyTable AnotherTable

Suporte a vários esquemas

O mssql-django backend estende o inspectdb para oferecer suporte a vários esquemas. Especifique um esquema com o --schema sinalizador:

python manage.py inspectdb --schema "dbo"
python manage.py inspectdb --schema "sales"

Esse recurso é útil para bancos de dados SQL Server que organizam tabelas em vários esquemas.

Trabalhar com modelos de vários esquemas

Quando o banco de dados usa vários esquemas, use db_table na classe do modelo para qualificar a tabela com o nome do Meta esquema. Os modelos gerados a partir de inspectdb podem não incluir prefixos de esquema, portanto, adicione-os manualmente:

class Customer(models.Model):
    customer_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=200)

    class Meta:
        managed = False
        db_table = "[sales].[Customer]"

class Product(models.Model):
    product_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)

    class Meta:
        managed = False
        db_table = "[inventory].[Product]"

Importante

Use um nome de duas partes entre colchetes, como "[schema].[table]". O backend trata db_table como um único identificador, de modo que os nomes entre colchetes são preservados corretamente, enquanto as formas entre aspas duplas são novamente colocadas entre aspas como um nome literal de tabela.

Chaves estrangeiras entre esquemas

O Django pode seguir relações de chave estrangeira entre esquemas, desde que ambas as tabelas estejam no mesmo banco de dados e os db_table valores sejam definidos corretamente:

class OrderItem(models.Model):
    order_item_id = models.AutoField(primary_key=True)
    product = models.ForeignKey("Product", on_delete=models.CASCADE)
    quantity = models.IntegerField()

    class Meta:
        managed = False
        db_table = "[sales].[OrderItem]"

O Django resolve o ForeignKey por meio do valor de db_table do modelo referenciado, portanto não é necessária nenhuma configuração adicional de esquema no campo de relacionamento.

Examinar modelos gerados

O inspectdb comando gera um código de modelo que pode precisar de ajustes manuais:

  1. Set managed = False: os modelos gerados incluem managed = False na classe Meta, o que significa que o Django não gerencia o esquema da tabela. Remova essa linha se você quiser que o Django gerencie migrações para a tabela.

  2. Adicionar chaves primárias: se uma tabela não tiver uma chave primária que inspectdb possa detectar, talvez seja necessário adicionar uma manualmente.

  3. Corrigir campos de relacionamento: relações de chave estrangeira podem precisar de ajustes, especialmente para referências entre esquemas.

Exemplo de saída gerada:

class Product(models.Model):
    product_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    created_at = models.DateTimeField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = "Product"

Limitations

O inspectdb comando tem as seguintes limitações quando usado com SQL Server.

Inspeção de chave primária composta

Tabelas com chaves primárias compostas podem não gerar definições de modelo completas. No Django 5.2 e posterior, defina CompositePrimaryKey manualmente após a execução inspectdbou use uma chave primária alternativa.

Views

O inspectdb comando pode inspecionar exibições, mas os modelos gerados podem exigir ajuste manual de tipos de campo e restrições nulas.