2011-02-18 74 views
22

我在MySQL數據庫中有幾個臨時表,它們共享相同的模式並具有動態名稱。我將如何使用Django與這些表接口?單個模型可以從多個表中繪製數據嗎?單個Django模型,多個表?

+0

你可以按照下面的更新動態設置它。 – 2011-02-28 22:58:26

回答

21

我相信你可以做一個工廠函數,它會返回你的模型的動態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() 
+1

我認爲你的第一個解決方案在我的情況下更好,因爲我將擁有任意數量的必須連接的表,我不確定動態設置它是否是線程安全的解決方案。我發現的問題是,測試時會出現奇怪的結果,也就是說需要花些時間來加載裝置,甚至會出現一些奇怪的現象。 – exupero 2011-03-01 03:10:53

+1

對於您的第一個解決方案,它看起來像`db_table`卡在任何第一次分配。它可以被重新分配,但它被重新分配給每個類的實例(換句話說,似乎只有一個`_meta`實例)。 – exupero 2011-05-19 17:25:14

7

動態創建表格的模型。

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)...']