【问题标题】:How to generate sql from Django model definition?如何从 Django 模型定义生成 sql?
【发布时间】:2018-03-01 03:13:31
【问题描述】:

我的目的是动态生成 Django 模型。
我使用以下代码创建模型。

def create_model(name, fields=None, app_label='', module='', options=None, admin_opts=None):
  class Meta:
    # Using type('Meta', ...) gives a dictproxy error during model creation
    pass

  if app_label:
    # app_label must be set using the Meta inner class
    setattr(Meta, 'app_label', app_label)

  # Update Meta with any options that were provided
  if options is not None:
    for key, value in options.iteritems():
        setattr(Meta, key, value)

  # Set up a dictionary to simulate declarations within a class
  attrs = {'__module__': module, 'Meta': Meta}

  # Add in any fields that were provided
  if fields:
    attrs.update(fields)

  # Create the class, which automatically triggers ModelBase processing
  model = type(name, (models.Model,), attrs)

  # Create an Admin class if admin options were provided
  if admin_opts is not None:
    class Admin(admin.ModelAdmin):
        pass
    for key, value in admin_opts:
        setattr(Admin, key, value)
    admin.site.register(model, Admin)
  return model

然后我知道我需要从模型生成 sql 并同步到数据库中。
我使用以下代码:

def install(custom_model):
  from django.core.management import color
  from django.db import connection
  from django.db.backends.base import schema
  style = color.no_style()
  cursor = connection.cursor()
  statements, pending =  connection.creation.sql_create_model(custom_model, style)
  for sql in statements:
    cursor.execute(sql)

但是,它告诉我
AttributeError: 'DatabaseCreation' object has no attribute 'sql_create_model'
我的 Django 版本是 2.0,是的,它没有 sql_create_model。
我的问题是如何使用 Django 2.0 从模型生成 sql?
非常感谢。

【问题讨论】:

    标签: django-models


    【解决方案1】:

    我找到了解决办法

    from django.db import connection
    
    with connection.schema_editor() as editor:
        editor.create_model(model)
    

    注意 如果Meta中有unique_together,'with'语句是必要的,因为deferred_sql是在__enter__方法中定义的,否则你会得到没有属性'deferred_sql'的异常。请检查 backends/base/schema.py 中的 django 'BaseDatabaseSchemaEditor' 代码

    class BaseDatabaseSchemaEditor:
        ... ...
    
        def __enter__(self):
            self.deferred_sql = []
            if self.atomic_migration:
                self.atomic = atomic(self.connection.alias)
                self.atomic.__enter__()
            return self
    
        ... ...
    
        def create_model(self, model):
            ... ...
    
            # Add any unique_togethers (always deferred, as some fields might be
            # created afterwards, like geometry fields with some backends)
            for fields in model._meta.unique_together:
                columns = [model._meta.get_field(field).column for field in fields]
                self.deferred_sql.append(self._create_unique_sql(model, columns))
            ... ...
    

    【讨论】:

    • 这似乎不适用于 SQLite
    • django.db.utils.NotSupportedError: SQLite schema editor cannot be used while foreign key constraint checks are enabled. Make sure to disable them before entering a transaction.atomic() context because SQLite does not support disabling them in the middle of a multi-statement transaction.
    猜你喜欢
    • 2011-01-16
    • 2023-03-14
    • 2017-05-15
    • 1970-01-01
    • 1970-01-01
    • 2012-07-01
    • 2020-03-24
    • 2011-11-18
    相关资源
    最近更新 更多