2010-05-04 46 views
19

我們需要創建SQLAlchemy類來訪問隨着時間的推移會增加的多個外部數據源。我們對我們的核心ORM模型使用聲明性基礎,我知道我們可以使用autoload = True手動指定新的ORM類來自動生成映射。SQLAlchemy中的動態類創建

的問題是,我們需要能夠產生動態他們採取這樣的事情:

from sqlalchemy.ext.declarative import declarative_base 
Base = declarative_base() 

stored={} 
stored['tablename']='my_internal_table_name' 
stored['objectname']='MyObject' 

,並把它變成像這樣動態:

​​

我們不希望類持續時間超過打開連接所需的時間,執行查詢,然後關閉連接。因此,理想情況下,我們可以將上述「存儲」變量中的項目放到數據庫中,並根據需要提取它們。另一個挑戰是對象名稱(例如「MyObject」)可能在不同的連接上使用,所以我們無法定義它並保留它。

有關如何完成這項任何建議將不勝感激。

謝謝...

回答

24

您可以使用3-argument call to type動態創建MyObject

type(name, bases, dict) 

    Return a new type object. This is essentially a dynamic form of the 
    class statement... 

例如:

mydict={'__tablename__':stored['tablename'], 
     '__table_args__':{'autoload':True},} 

MyObj=type(stored['objectname'],(Base,),mydict) 
print(MyObj) 
# <class '__main__.MyObject'> 
print(MyObj.__base__) 
# <class '__main__.Base'> 
print(MyObj.__tablename__) 
# my_internal_table_name 
print(MyObj.__table_args__) 
# {'autoload': True} 
+0

孩子......我覺得愚蠢。這種簡單的解決方案。我沒有意識到這種類型的方法非常強大。 我稍微修改瞭解決方案,將對象名稱放在全局空間中,以便它可以直接包含在SQLAlchemy查詢中: globals()[stored ['objectname']] = type(stored ['objectname'],(基地,),mydict) 謝謝...偉大的解決方案。 – PlaidFan 2010-05-04 21:23:13

+3

不要覺得愚蠢!我通過觀看其他人在SO上使用它來了解了這個技巧。現在你也知道這個訣竅,並且可以令你的朋友驚歎。 :) – unutbu 2010-05-04 21:34:26