首页 文章

SQLAlchemy创建动态表和列

提问于
浏览
1

我试图使用这些信息动态创建表格,并且一直在使用论坛帖子来更好地了解如何实现这一目标 . 所以我想根据我检索的信息创建表 - 数据库和列信息(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

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

    Column 初始化程序中的 nullable 参数应该具有 bool 类型,但是您尝试传递 str 对象 nulls ,对于 pkprimary_key 参数也是如此 .

    此外,您正在尝试在理解中覆盖名称 ctypepknulls ,这是不正确的并且在给定异常时会引发 . 您应该在理解中重命名从 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']) 并且它有效,给定的表可以简单地获得

    test = post_meta.tables['customers']
    

    没有从头开始构建 .

  • 4

    谢谢你的代码 . 帮了我很多忙 .

    也适用于会话:

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

相关问题