使用 inspectdb 进行模型逆向工程

本文介绍如何使用 Django 的管理inspectdb命令从现有SQL Server数据库生成模型代码。

先决条件

settings.py 中,将 mssql 添加到您的 INSTALLED_APPS。 此步骤注册 mssql-django 管理命令重写 inspectdb,这会添加 --schema 用于检查非默认架构的标志:

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

Note

数据库 mssql 后端在没有此步骤的情况下工作。 仅在启用inspectdb上的--schema标志时,才需要将"mssql"添加到INSTALLED_APPS中。 如果没有它, inspectdb 则仅检查默认架构(dbo)。

基本用法

为配置数据库中的所有表生成模型:

python manage.py inspectdb

将输出直接保存到模型文件:

python manage.py inspectdb > myapp/models.py

查看特定的表

仅为特定表生成模型:

python manage.py inspectdb MyTable AnotherTable

多架构支持

后端 mssql-django 扩展 inspectdb 以支持多个架构。 使用 --schema 标志指定架构:

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

此功能适用于SQL Server跨多个架构组织表的数据库。

使用来自多个架构的模型

当数据库使用多个架构时,请在模型的 Meta 类中使用 db_table,通过架构名称来限定表名。 生成的 inspectdb 模型可能不包含架构前缀,因此请手动添加它们:

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]"

Important

使用带括号的两部分名称,例如 "[schema].[table]"。 后端将 db_table 视为一个单独的标识符,因此方括号括起来的名称会被正确保留,而双引号形式则会被重新加上引号,作为字面表名处理。

跨架构外键

只要两个表位于同一数据库中并且 db_table 值设置正确,Django 就可以跨架构遵循外键关系:

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]"

Django 通过被引用模型的 db_table 值来解析 ForeignKey,因此关系字段上不需要额外的 schema 配置。

查看生成的模型

inspectdb 命令生成可能需要手动调整的模型代码:

  1. Set managed = False:生成的模型在 Meta 类中包含 managed = False,这意味着 Django 不管理表结构。 如果希望 Django 管理表的迁移,请删除此行。

  2. 添加主键:如果表没有可以检测的主键 inspectdb ,则可能需要手动添加一个。

  3. 修复关联字段:外键关系可能需要调整,尤其是跨模式引用。

生成的输出示例:

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

与SQL Server一起使用时,该inspectdb命令具有以下限制。

复合主键检查

具有复合主键的表可能不会生成完整的模型定义。 在 Django 5.2 及更高版本中,运行 inspectdb 后手动定义 CompositePrimaryKey,或使用代理主键。

Views

inspectdb 命令可以检查视图,但生成的模型可能需要手动调整字段类型和 null 约束。