我目前正在使用sqlalchemy的金字塔系統。SQLAlchemy數據庫反射模型創建
該系統將包含一個存儲在 數據庫表中的模型(我們稱之爲基礎)。該模型應該可以在運行時由用戶擴展。基本上,用戶 應該能夠繼承Base並創建一個新模型(讓我們稱之爲'Child')。 孩子應該存儲在另一個數據庫表中。
所有可用的例子似乎都處理預定義模型上的數據庫反射。 什麼是通過數據庫反射生成完整模型類的最佳方法?
我目前正在使用sqlalchemy的金字塔系統。SQLAlchemy數據庫反射模型創建
該系統將包含一個存儲在 數據庫表中的模型(我們稱之爲基礎)。該模型應該可以在運行時由用戶擴展。基本上,用戶 應該能夠繼承Base並創建一個新模型(讓我們稱之爲'Child')。 孩子應該存儲在另一個數據庫表中。
所有可用的例子似乎都處理預定義模型上的數據庫反射。 什麼是通過數據庫反射生成完整模型類的最佳方法?
我只是解決了使用下面的代碼片段上述問題:
table = Table('anExistingTable', Base.metadata, autoload=True, autoload_with=Session.bind)
Extension = type('Extension', (BaseClass,), {
'__table__' : table,
'__mapper_args__' : {
'inherits': BaseClass,
'polymorphic_identity': 'extension'
}
})
不過,我不知道爲什麼第一次嘗試沒有成功......
這似乎與「數據庫反射」沒有太大關係,而是動態創建表。這是一個非常危險的操作,並且通常會被折磨。
您應該嘗試思考如何建模用戶想要添加到Base中的可能結構,並圍繞該模式設計架構。有時這些靈活的結構可以從垂直表格中受益,當你不知道列可能是什麼時。
不要忘記,有一整套數據存儲系統可以爲「無模式」模型提供更靈活的支持。像Mongo或ZODB可能在這裏更有意義。
這個概念大部分對我來說都很好,但我無法將現有表綁定到使用多表繼承的新創建的類。下面是一些代碼,以使事情更清楚:
Base.metadata.reflect(bind=Session.bind)
table = Base.metadata.tables['anExistingTable']
Extension = type('Extension', (BaseClass,), {})
orm.mapper(Extension, table, inherits=orm.class_mapper(BaseClass),
polymorphic_identity='extension')
這將導致以下錯誤:
ArgumentError: Class '<class 'Extension'>' already has a primary mapper defined. Use non_primary=True to create a non primary Mapper. clear_mappers() will remove *all* current mappers from all classes.
你有任何想法,爲什麼有一個類定義主映射剛剛產生的?
只要定義一個生成方法
def mapClass(class_name, table_name):
# Allows to generate previously undefined mapped classes, remapping when necessary
#For security reason this will only map a class
#when class is not previously declared
#or if declared, when is a MappableClass subclass,
#this way we prevent to map any class.
#Even when not able to return a mapped class it will return corresponding class_name class
#if so, we'll get an error when accessing non existing MappableClass members
if not globals.has_key(class_name):
cls=type(class_name, (MappableClass,), {})
globals[class_name]=cls
else:
cls=globals[class_name]
if issubclass(cls,MappableClass):
tab_obj=Table(table_name,meta,autoload=True)
mapper(cls, tab_obj)
return cls
或here 我增加了發電機方法在答題的類靜態繼承發電機類,所以我可以同時使用以前聲明的子類或新dinamically創建, 那些。
嗨,謝謝爲答案。但是,你知道如何將多表繼承的概念(見下文)轉化爲這個概念嗎? – fynn
呃...我不知道sqlalchemy如何處理表繼承...是否將繼承信息存儲在數據庫中? (對不起,而不是回答)如果不是,你需要將它存儲起來,並在上課時檢索它。無論如何,您可以將繼承映射參數添加到mapClass方法 – Kelbethor
是的,多態類型存儲在數據庫中([see here](http://www.sqlalchemy.org/docs/orm/inheritance.html#joined-table-遺產))。但我很難找到數據庫反射和繼承組合的解決方案。 – fynn