使用 SQLAlchemy 元数据获取现有表

新手上路,请多包涵

我有一个已经存在的表:

 USERS_TABLE = Table("users", META_DATA,
                    Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
                    Column("first_name", String(255)),
                    Column("last_name", String(255))
                   )

我通过运行这个创建了这个表:

 CONN = create_engine(DB_URL, client_encoding="UTF-8")
META_DATA = MetaData(bind=CONN, reflect=True)
# ... table code
META_DATA.create_all(CONN, checkfirst=True)

它第一次工作,我能够创建表格。但是,我第二次收到此错误:

 sqlalchemy.exc.InvalidRequestError: Table 'users' is already defined for this MetaData instance.  Specify 'extend_existing=True' to redefine options and columns on an existing Table object.

这是有道理的,因为表 users 已经存在。我能够看到该表是否存在,如下所示:

 TABLE_EXISTS = CONN.dialect.has_table(CONN, "users")

但是,我如何实际获取现有的表对象?我在文档中的任何地方都找不到这个。请帮忙。

原文由 dopatraman 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
1 个回答

我们这里有 3 种不同的方法:

  • 假设已经创建了所需的表,反映它们并使用 MetaData.tables 字典字段
from sqlalchemy import MetaData, create_engine

CONN = create_engine(DB_URL, client_encoding="UTF-8")

META_DATA = MetaData(bind=CONN, reflect=True)

USERS_TABLE = META_DATA.tables['users']

  • MetaData 对象初始化中删除 reflect 标志,因为我们不使用它而且 - 试图创建已经反映的表:
 from sqlalchemy import (MetaData, Table, Column, Integer, String, Sequence,
                        create_engine)

CONN = create_engine('sqlite:///db.sql')

META_DATA = MetaData(bind=CONN)

USERS_TABLE = Table("users", META_DATA,
                    Column("id", Integer, Sequence("user_id_seq"),
                           primary_key=True),
                    Column("first_name", String(255)),
                    Column("last_name", String(255)))

META_DATA.create_all(CONN, checkfirst=True)

  • 假设我们保留反射表,如果它之前是通过在 Table 对象初始化器 keep_existing 标志 True
 from sqlalchemy import (MetaData, Table, Column, Integer, String, Sequence,
                        create_engine)

CONN = create_engine('sqlite:///db.sql')

META_DATA = MetaData(bind=CONN, reflect=True)

USERS_TABLE = Table("users", META_DATA,
                    Column("id", Integer, Sequence("user_id_seq"),
                           primary_key=True),
                    Column("first_name", String(255)),
                    Column("last_name", String(255)),
                    keep_existing=True)

META_DATA.create_all(CONN, checkfirst=True)

选择哪一个?取决于你的用例,但我更喜欢第二个,因为它看起来你没有使用反射,而且它是最简单的修改:只需从 MetaData 初始值设定项中删除标志。


聚苯乙烯

我们总是可以在初始化 MetaData 对象后使用 MetaData.reflect 方法进行反射:

 META_DATA.reflect()

我们还可以指定要反映哪些表 only 参数(可以是 str 对象的任何 可迭代 对象):

 META_DATA.reflect(only=['users'])

还有更多

原文由 Azat Ibrakov 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏