SQLAlchemy创建动态表和列

时间:2017-05-01 15:28:59

标签: python sqlalchemy

我尝试根据我检索的数据动态创建数据库表和列。 我检索数据库列表,列名和列属性列表,如列类型,primary_key / unique,nullable以及其他元数据。 我试图使用这些信息动态创建表格,并一直在使用论坛帖子来更好地了解如何实现这一点。所以我想根据我检索的信息创建表 - 数据库和列信息(colnames和列类型,主键和可空信息。检索到的信息可能每天或每周更改。 论坛帖子#1 - Sqlalchemy dynamically create table and mapped class

postgresql_db = engine(...)

post_meta = sql.MetaData(bind=postgresql_db.engine)

post_meta.reflect(schema='customers')

connection = postgresql_db.engine.connect()

col_names = ['id', 'fname', 'lname', 'age']
ctype = ['Integer', 'String', 'String', 'Integer']
pk = ['True', 'False', 'False', 'False']
nulls = ['No', 'No', 'No', 'No']

class test(object):

     test = Table('customers', post_meta,
              *(Column(col, ctype, primary_key=pk, nullable=nulls)
           for col, ctype, pk, nulls in zip(col_names, ctype, pk, nulls))

test.create()

有错误消息: AttributeError: 'list' object has no attribute _set_parent_with_dispatch 似乎无法确定此错误所指的是什么。

回溯:

Traceback (most recent call last):
  File "C:/Users/xxx/db.py", line 247, in <module>
    main()
  File "C:/Users/xxx/db.py", line 168, in main
    for col, ctype, pk, nulls in zip(col_names, ctype, pk, nulls)
  File "C:/Users/xxx/apidb.py", line 168, in <genexpr>
    for col, ctype, pk, nulls in zip(col_names, ctype, pk, nulls)
  File "C:\Python27\lib\site-packages\sqlalchemy\sql\schema.py", line 1234, in __init__
    self._init_items(*args)
  File "C:\Python27\lib\site-packages\sqlalchemy\sql\schema.py", line 79, in _init_items
    item._set_parent_with_dispatch(self)
AttributeError: 'list' object has no attribute '_set_parent_with_dispatch'

任何想法我做错了什么?

2 个答案:

答案 0 :(得分:6)

这里有很多不正确的事情。

nullable初始化程序中的

Column参数应该具有bool类型,但您尝试传递str对象nulls,{{1} }和pk参数。

此外,您正在尝试在理解中覆盖名称primary_keyctypepk,这是不正确的,并且会在异常情况下提升。 您应该在理解中重命名从nulls生成的对象。

zip无法识别字符串SQLAlchemy'Integer',它们不是有效的'String'类型。

如果您想反映名为Column的特定表格,则应使用参数'customers'而不是only来完成,并且名称应为schema

此外,您不需要课程list

您的代码可能看起来像

test

最后,如果你from sqlalchemy import MetaData, Table, Column, Integer, String postgresql_db = engine(...) post_meta = MetaData(bind=postgresql_db.engine) post_meta.reflect(only=['customers']) connection = postgresql_db.engine.connect() columns_names = ['id', 'fname', 'lname', 'age'] columns_types = [Integer, String, String, Integer] primary_key_flags = [True, False, False, False] nullable_flags = [False, False, False, False] test = Table('customers', post_meta, *(Column(column_name, column_type, primary_key=primary_key_flag, nullable=nullable_flag) for column_name, column_type, primary_key_flag, nullable_flag in zip(columns_names, columns_types, primary_key_flags, nullable_flags))) test.create() 并且它有效,那么只需通过

获得给定的表格
post_meta.reflect(only=['customers'])

没有从头开始构建。

答案 1 :(得分:0)

感谢您提供代码。对我有很大帮助。

也可用于会话:

 meta_data = MetaData(bind = session.get_bind())