Обратное проектирование моделей с помощью inspectdb

В этой статье объясняется, как использовать команду управления Django inspectdb для создания кода модели из существующей базы данных SQL Server.

Необходимые условия

Добавьте mssql в свой INSTALLED_APPS в settings.py. На этом шаге регистрируется переопределение команды управления 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 часть базы данных работает без этого шага. Добавление "mssql" к INSTALLED_APPS требуется только для включения флага --schema на inspectdb. Без него 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, которые упорядочивают таблицы по нескольким схемам.

Работа с моделями из нескольких схем

Если в базе данных используется несколько схем, используйте db_table в классе модели Meta, чтобы указать таблицу вместе с именем схемы. Модели, созданные из 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 как единый идентификатор, поэтому имена в квадратных скобках сохраняются корректно, а формы в двойных кавычках повторно заключаются в кавычки как буквальное имя таблицы.

Внешние ключи между схемами

Django может следовать связям внешнего ключа между схемами, если обе таблицы находятся в одной базе данных, и db_table значения задаются правильно:

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 определяет ForeignKey по значению db_table связанной модели, поэтому в поле связи не требуется дополнительная настройка схемы.

Проверка созданных моделей

Команда inspectdb создает код модели, который может потребовать ручной корректировки:

  1. Set managed = False: Созданные модели содержат managed = False в классе Meta, что означает, что 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"

Ограничения

Команда inspectdb имеет следующие ограничения при использовании с SQL Server.

Проверка составного первичного ключа

Таблицы с составными первичными ключами могут не создавать полные определения модели. В Django 5.2 и более поздних версиях определите CompositePrimaryKey вручную после выполнения inspectdbили используйте суррогатный первичный ключ.

Views

Команда inspectdb может проверять представления, но созданные модели могут потребовать ручной настройки типов полей и ограничений NULL.