4

我一直在寻找一种方法来定义数据库表并通过 Django API 更改它们。

例如,我想编写一些直接操作表 DDL 的代码,并允许我以编程方式按需定义表或将列添加到表中(无需运行同步数据库)。我意识到可能会想到 django-south 和 django-evolution,但我并不认为这些工具是旨在集成到应用程序中并由最终用户使用的工具......相反,这些工具是用于升级您的数据库表。我正在寻找可以执行以下操作的东西:

class MyModel(models.Model):  # wouldn't run syncdb.. instead do something like below
    a = models.CharField()
    b = models.CharField()

model = MyModel()
model.create()  # this runs the create table (instead of a syncdb)

model.add_column(c = models.CharField())  # this would set a column to be added
model.alter()   # and this would apply the alter statement 

model.del_column('a')   # this would set column 'a' for removal 
model.alter()   # and this would apply the removal 

这只是一个关于这种 API 如何工作的玩具示例,但重点是我很想知道是否有一种方法可以像这样以编程方式创建和更改表。这对于诸如内容管理系统之类的东西可能很有用,其中人们可能想要动态创建一个新表。另一个例子是存储任意宽度数据集的站点,需要通过接口或数据导入动态生成表。有人知道动态创建和更改这样的表的任何好方法吗?

(当然,我知道可以对数据库执行直接 SQL 语句,但该解决方案缺乏将数据库视为对象的能力)

只是好奇人们是否对此有任何建议或方法......

4

2 回答 2

2

很快从我的头顶上掉下来..

使用 Create/Alter 方法创建自定义管理器。

于 2010-10-11T21:07:55.743 回答
2

您可以尝试与管理数据库更改的 django 代码交互。它有点受限(例如,据我所知,没有 ALTER),但您可以扩展它。这是来自django.core.management.commands.syncdb.

for app in models.get_apps():
        app_name = app.__name__.split('.')[-2]
        model_list = models.get_models(app)
        for model in model_list:
            # Create the model's database table, if it doesn't already exist.
            if verbosity >= 2:
                print "Processing %s.%s model" % (app_name, model._meta.object_name)
            if connection.introspection.table_name_converter(model._meta.db_table) in tables:
                continue
            sql, references = connection.creation.sql_create_model(model, self.style, seen_models)
            seen_models.add(model)
            created_models.add(model)
            for refto, refs in references.items():
                pending_references.setdefault(refto, []).extend(refs)
                if refto in seen_models:
                    sql.extend(connection.creation.sql_for_pending_references(refto, self.style, pending_references))
            sql.extend(connection.creation.sql_for_pending_references(model, self.style, pending_references))
            if verbosity >= 1 and sql:
                print "Creating table %s" % model._meta.db_table
            for statement in sql:
                cursor.execute(statement)
            tables.append(connection.introspection.table_name_converter(model._meta.db_table))

看看connection.creation.sql_create_model。该creation对象是在与您在 settings.py 中使用的数据库相关的数据库后端中创建的。他们都在django.db.backends.

如果您必须拥有 ALTER 表,我认为您可以创建自己的自定义后端来扩展现有的后端并添加此功能。然后您可以通过您创建的 ExtendedModelManager 直接与它交互。

于 2010-10-12T08:45:20.233 回答