sin*_*ton 7 python django postgresql django-models django-queryset
我目前正在使用Django框架,包括其模型机制来抽象数据库模式声明和一般数据库访问,这在大多数情况下都能正常工作.
但是,我的应用程序还需要在运行时动态创建和访问表,据我所知,Django不支持开箱即用.
这些表通常具有相同的结构,并且基本上可以由相同的Model类抽象,但是Django不允许您更改某个模型查询的基础db_table,因为它在Model类上而不是在Manager上声明.
我的解决方案是每当我需要创建,填充和访问新表时执行此过程:
当我需要访问该表(使用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
Run Code Online (Sandbox Code Playgroud)请注意,我确实检查模型是否已在django中注册,并且我正在使用现有模型.模型名称对于每个表始终是唯一的.由于我使用的是多租户,因此租户名称也是模型名称的一部分,以避免与在不同模式上声明的类似表冲突.
到目前为止,这个解决方案对我来说很好 但是,应用程序需要支持大量这些表.即10,000 - 100,000个这样的表(和相应的模型类),每个表有多达一百万行.
假设这个负载的基础数据库很好,我的问题是:
您是否看到此解决方案有任何问题,无论是否达到预期规模?
任何人都有更好的解决方案吗?
谢谢.
有一个关于动态创建模型的 wiki 页面,尽管距离上次更新已经有一段时间了:
还有一些应用程序是为此用例设计的,但我认为它们中的任何一个都没有得到积极维护:
我知道如果你已经致力于 Django,这不是很有帮助,但这是一个 Django 并不是很好的用例。对抗 Django 模型层提供的抽象可能比仅使用 psycopg2 或任何其他适合您的数据的适配器的成本更高。
根据您要对数据执行的操作类型,使用带有索引字段的单个模型也可能更合理,该模型允许您区分该行将在哪个表中,然后按该列对数据进行分片.
如果您仍然需要这样做,一般的想法是:
创建一个扩展 Django 的 ModelBase 的元类。您将使用此元类作为实际模型的工厂。
考虑该 wiki 页面上提到的内容,例如绕过 app_label 问题。
生成并执行用于创建模型的 sql,如 wiki 页面上所示。
| 归档时间: |
|
| 查看次数: |
7187 次 |
| 最近记录: |