我目前正在使用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