Sqlalchemy 动态创建表和映射类

Posted

技术标签:

【中文标题】Sqlalchemy 动态创建表和映射类【英文标题】:Sqlalchemy dynamically create table and mapped class 【发布时间】:2017-07-04 19:09:45 【问题描述】:

给定一组列名及其类型,目标是 实例化一个表和对应的映射类。

与此处发布的问题有关:Dynamic Class Creation in SQLAlchemy。

到目前为止,我有以下内容:

table = Table(tbl, 
              metadata, 
             *(Column(col, ctype, primary_key=pk, index=idx) for  col,  ctype, pk, idx in zip(attrs, types, primary_keys, indexes))
              )

这将创建表格对象。现在我需要创建相应的类。

mydict='__tablename__':tbl
cls = type(cls_name, (Base,), mydict)

这给了我以下错误:

ArgumentError: Mapper Mapper|persons_with_coord|t_persons_w_coord 无法为映射表组装任何主键列

我的问题是如何将主键指定为类创建的一部分。 创建类后,我是否需要按如下方式调用映射器:

mapper(cls, table)

【问题讨论】:

【参考方案1】:

mydict 映射必须包含一个表对象或指定需要从数据库加载该表。

这应该可以工作

mydict='__tablename__':tbl, '__table__': table

这也应该有效

mydict='__tablename__':tbl, '__table_args__': ('autoload':True,)

创建table 时已经指定了主键。创建声明时不必再次指定它们,但是如果需要(例如,对于复杂键),则应在 __table_args__ 中指定。

必须在声明性类上调用映射器。但是,新创建的声明没有元数据对象。添加元数据将使动态创建的声明的行为更多类似于常规声明,因此我建议将此行放在类创建之后

cls.metadata = cls.__table__.metadata

所以,完整的编辑可能是:

mydict='__tablename__':tbl, '__table__': table
cls = type(cls_name, (Base,), mydict)
cls.metadata = cls.__table__.metadata

【讨论】:

以上是关于Sqlalchemy 动态创建表和映射类的主要内容,如果未能解决你的问题,请参考以下文章

sqlalchemy根据表名动态创建model类

sqlalchemy 动态映射

如何在 SQLAlchemy 中使用动态关系映射层次结构?

基于表库动态创建sqlAlchemy Metaclass

如何将ACCESS的表和查询创建成动态的WEB?

如何使用 SQLAlchemy Postgres ORM 的声明性基础动态创建具有列名和字典约束的表?