Sqlalchemy动态创建表和映射类

时间:2017-02-15 22:06:07

标签: python sqlalchemy metaprogramming metaclass declarative

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

与此处发布的问题相关: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:

mapper(cls, table)

1 个答案:

答案 0 :(得分:0)

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