【发布时间】:2011-06-29 12:17:09
【问题描述】:
我在 MySQL 数据库中有几个临时表,它们共享相同的架构并具有动态名称。我将如何使用 Django 与这些表进行交互?单个模型可以从多个表中提取数据吗?
【问题讨论】:
-
你可以动态设置它如下更新。
我在 MySQL 数据库中有几个临时表,它们共享相同的架构并具有动态名称。我将如何使用 Django 与这些表进行交互?单个模型可以从多个表中提取数据吗?
【问题讨论】:
我相信,您可以创建一个工厂函数,以动态 db_table 返回您的模型。
def getModel(db_table):
class MyClass(models.Model):
# define as usual ...
class Meta:
db_table = db_table
return MyClass
newClass = getModel('29345794_table')
newClass.objects.filter( ...
编辑:Django 不会在每次调用此函数时创建类的 _meta 属性的新实例。为_meta 创建一个新实例取决于类的名称(Django 必须将其缓存在某处)。元类可用于在运行时更改类的名称:
def getModel(db_table):
class MyClassMetaclass(models.base.ModelBase):
def __new__(cls, name, bases, attrs):
name += db_table
return models.base.ModelBase.__new__(cls, name, bases, attrs)
class MyClass(models.Model):
__metaclass__ = MyClassMetaclass
class Meta:
db_table = db_table
return MyClass
不确定是否可以在已定义的类上动态设置。我自己没有这样做,但它可能会起作用。
您可以随时设置。
>>> MyModel._meta.db_table = '10293847_table'
>>> MyModel.objects.all()
【讨论】:
db_table 似乎卡在了第一个分配的位置。可以重新赋值,但是对于类的每一个实例都会重新赋值(换句话说,好像_meta的实例只有一个)。
MyModel._meta.db_table会不会很危险?
为您的表格动态创建模型。
from django.db import models
from django.db.models.base import ModelBase
def create_model(db_table):
class CustomMetaClass(ModelBase):
def __new__(cls, name, bases, attrs):
model = super(CustomMetaClass, cls).__new__(cls, name, bases, attrs)
model._meta.db_table = db_table
return model
class CustomModel(models.Model):
__metaclass__ = CustomMetaClass
# define your fileds here
srno = models.IntegerField(db_column='SRNO', primary_key=True)
return CustomModel
你可以开始查询数据库了。
In [6]: t = create_model('trial1')
In [7]: t._meta.db_table
Out[7]: 'trial1'
In [8]: t.objects.all() # default db
Out[8]: [<CustomModel: CustomModel object>, '(remaining elements truncated)...']
In [9]: t.objects.using('test').all() # test db
Out[9]: [<CustomModel: CustomModel object>, '(remaining elements truncated)...']
【讨论】:
models.Model 的模型都会被缓存。所以meta class需要设置不同的model name(缓存键),设置不同的model._meta.db_table。