【问题标题】:SQLAlchemy create dynamic tables and columnsSQLAlchemy 创建动态表和列
【发布时间】:2017-09-29 00:29:36
【问题描述】:

我正在尝试根据我检索的数据动态创建数据库表和列。 我检索数据库列表、列名称和属性列表,例如列类型、primary_key / 唯一、可为空以及其他元数据。 我正在尝试使用这些信息来动态创建表格,并且一直在使用论坛帖子来更好地了解如何实现这一点。所以我想根据我检索到的信息创建表 - 数据库和列信息(列名和列类型、主键和可为空的信息。检索到的信息可能每天或每周更改。 论坛帖子 #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'

任何想法我做错了什么?

【问题讨论】:

  • 请包括完整的回溯,包括行号等。
  • 我建议您从tutorial开始使用 SQLAlchemy
  • @AzatIbrakov 感谢您提供的信息,您的解决方案对我有用。我已经断断续续地阅读教程有一段时间了,可能我需要在更广泛的基础上获得更多知识。
  • 这意味着您将list 对象ctype 作为参数传递给Column 初始化程序的type_ 参数,但它应该是TypeEngine 子类之一(如String 和@ 987654332@)

标签: python sqlalchemy


【解决方案1】:

这里有很多不正确的地方。

Column 初始化器中的nullable 参数应该具有类型bool,但您正在尝试传递str 对象nullspkprimary_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']

无需从头开始构建。

【讨论】:

  • 这就是解决方案。错误很基本,谢谢指出
  • 你可以访问源数据库吗?
  • 没有。所有信息都是通过端点检索的,我没有直接访问源数据库的权限。
猜你喜欢
  • 2020-05-10
  • 2017-07-04
  • 2014-10-03
  • 2010-11-01
  • 1970-01-01
  • 2017-10-04
  • 2022-11-30
  • 2011-02-15
  • 2018-12-18
相关资源
最近更新 更多