【发布时间】:2015-10-28 09:32:34
【问题描述】:
我目前正在使用 Django 框架,包括其模型机制来抽象数据库模式声明和一般数据库访问,这在大多数情况下都可以正常工作。
但是,我的应用程序还需要在运行时动态创建和访问表,据我所知,Django 不支持开箱即用。
这些表通常具有相同的结构,并且基本上可以被同一个 Model 类抽象出来,但是 Django 不允许您更改某个模型查询的底层 db_table,因为它是在 Model 类上声明的,而不是在 Manager 上声明的。
我的解决方案是在需要创建、填充和访问新表时执行此过程:
- 使用原始 sql 创建和填充表
- 使用原始 sql 向表中添加索引
-
当我需要访问表时(使用 django queryset api),我动态声明一个新类型并将其作为查询模型返回,使用以下代码:
table_name = # name of the table created by sql model_name = '%d_%s' % (connection.tenant.id, table_name) try: model = apps.get_registered_model('myapp', model_name) return model except LookupError: pass logger.debug("no model exists for model %s, creating one" % model_name) class Meta: db_table = table_name managed = False attrs = { 'field1' : models.CharField(max_length=200), 'field2' : models.CharField(max_length=200), 'field3' : models.CharField(max_length=200) '__module__': 'myapp.models', 'Meta':Meta } model = type(str(model_name), (models.Model,), attrs) return model 请注意,我确实会检查模型是否已在 django 中注册,并且我正在使用现有模型以防万一。每个表的模型名称始终是唯一的。由于我使用的是多租户,因此租户名称也是模型名称的一部分,以避免与在不同架构上声明的类似表发生冲突。
- 如果不清楚:动态创建的表将并且应该永久保留以供将来的会话使用。
到目前为止,此解决方案对我来说效果很好。
但是,应用程序将需要支持大量此类表。即 10,000 - 100,000 个这样的表(和相应的模型类),每个表最多有一百万行。
假设底层数据库可以承受这种负载,我的问题是:
您是否认为此解决方案存在任何问题,无论是否考虑预期规模?
对于这种情况,有人有更好的解决方案吗?
谢谢。
【问题讨论】:
-
你熟悉ContentTypes吗?
-
谢谢。是的,我是,简短地说。但我看不出它如何有助于在运行时创建模型。不过,如果它已经注册,它可能有助于替换我检索现有模型的方式。
标签: python django postgresql django-models django-queryset