Django 按需创建/更改表

发布于 2024-09-27 08:24:58 字数 990 浏览 9 评论 0原文

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

例如,我想编写一些直接操作表 DDL 的代码,并允许我以编程方式按需定义表或向表添加列(无需运行syncdb)。我意识到 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 语句,但该解决方案缺乏将数据库视为对象的能力)

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

I've been looking for a way to define database tables and alter them via a Django API.

For example, I'd like to be write some code which directly manipulates table DDL and allow me to define tables or add columns to a table on demand programmatically (without running a syncdb). I realize that django-south and django-evolution may come to mind, but I don't really think of these tools as tools meant to be integrated into an application and used by and end user... rather these tools are utilities used for upgrading your database tables. I'm looking for something where I can do something like:

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 

This is just a toy example of how such an API would work, but the point is that I'd be very interested in finding out if there is a way to programatically create and change tables like this. This might be useful for things such as content management systems, where one might want to dynamically create a new table. Another example would be a site that stores datasets of an arbitrary width, for which tables need to be generated dynamically by the interface or data imports. Dose anyone know any good ways to dynamically create and alter tables like this?

(Granted, I know one can do direct SQL statements against the database, but that solution lacks the ability to treat the databases as objects)

Just curious as to if people have any suggestions or approaches to this...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

缱倦旧时光 2024-10-04 08:24:58

您可以尝试与管理数据库更改的 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_modelcreation 对象是在与您在 settings.py 中使用的数据库相关的数据库后端创建的。所有这些都位于 django.db.backends 下。

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

You can try and interface with the django's code that manages changes in the database. It is a bit limited (no ALTER, for example, as far as I can see), but you may be able to extend it. Here's a snippet from 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))

Take a look at connection.creation.sql_create_model. The creation object is created in the database backend relevant to the database you are using in your settings.py. All of them are under django.db.backends.

If you must have ALTER table, I think you can create your own custom backend that extends an existing one and adds this functionality. Then you can interface with it directly through a ExtendedModelManager you create.

手心的温暖 2024-10-04 08:24:58

快速从我的脑海中浮现出来..

使用创建/更改方法创建自定义管理器。

Quickly off the top of my head..

Create a Custom Manager with the Create/Alter methods.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文