版本: 2.0.36 |发行日期: 2024 年 10 月 15 日


SQLAlchemy 2.0 文档


SQLAlchemy 2.0 文档


家


常见问题解答


  • 安装

  • 连接 / 发动机

  • 元数据 / 架构¶

    • 当我说 table.drop() / metadata.drop_all() 时,我的程序挂起

    • SQLAlchemy 是否支持 ALTER TABLE、CREATE VIEW、CREATE TRIGGER、Schema Upgrade 功能?

    • 如何按依赖关系的顺序对 Table 对象进行排序?

    • 如何将 CREATE TABLE/ DROP TABLE 输出作为字符串获取?

    • 如何子类化 Table/Column 以提供某些行为/配置?

  • SQL 表达式

  • ORM 配置

  • 性能

  • 会话 / 查询

  • 第三方集成问题


家


  • 上一篇:连接 / 发动机

  • 下一篇:SQL 表达式

  • 当前位置:首页

    • 常见问题解答

  • 本页内容:

    • 元数据 / 架构

      • 当我说 table.drop() / metadata.drop_all() 时,我的程序挂起

      • SQLAlchemy 是否支持 ALTER TABLE、CREATE VIEW、CREATE TRIGGER、Schema Upgrade 功能?

      • 如何按依赖关系的顺序对 Table 对象进行排序?

      • 如何将 CREATE TABLE/ DROP TABLE 输出作为字符串获取?

      • 如何子类化 Table/Column 以提供某些行为/配置?


元数据 / 架构¶


  • 当我说 table.drop() / metadata.drop_all() 时,我的程序挂起


  • SQLAlchemy 是否支持 ALTER TABLE、CREATE VIEW、CREATE TRIGGER、Schema Upgrade 功能?


  • 如何按依赖关系的顺序对 Table 对象进行排序?


  • 如何将 CREATE TABLE/ DROP TABLE 输出作为字符串获取?


  • 如何子类化 Table/Column 以提供某些行为/配置?


当我说 table.drop() / metadata.drop_all() 时,我的程序挂起了¶


这通常对应于两个条件:1. 使用 PostgreSQL,它对表锁非常严格,以及 2. 您有一个连接仍处于打开状态,该连接包含表上的锁,并且与用于 DROP 语句的连接不同。这是该模式的最小版本:

connection = engine.connect()
result = connection.execute(mytable.select())

mytable.drop(engine)


在上图中,连接池连接仍处于签出状态;此外,上面的 Result 对象还维护了指向此连接的链接。如果使用“隐式执行”,则结果将保持此连接打开,直到结果对象关闭或所有行都用尽。


对 mytable.drop(engine) 的调用尝试在从 Engine 获取的第二个连接上发出 DROP TABLE,该连接将锁定。


解决方案是在发出 DROP TABLE 之前关闭所有连接:

connection = engine.connect()
result = connection.execute(mytable.select())

# fully read result sets
result.fetchall()

# close connections
connection.close()

# now locks are removed
mytable.drop(engine)


SQLAlchemy 是否支持 ALTER TABLE、CREATE VIEW、CREATE TRIGGER、Schema Upgrade 功能?¶


SQLAlchemy 中不直接存在常规 ALTER 支持。对于临时的特殊 DDL,可以使用 DDL 和相关构造。有关此主题的讨论,请参阅 Customizing DDL 。


更全面的选项是使用架构迁移工具,例如 Alembic 或 SQLAlchemy-Migrate;有关此内容的讨论,请参阅 通过迁移更改数据库对象 。


如何按依赖关系的顺序对 Table 对象进行排序?¶


这可以通过 MetaData.sorted_tables 函数获得:

metadata_obj = MetaData()
# ... add Table objects to metadata
ti = metadata_obj.sorted_tables
for t in ti:
    print(t)


如何将 CREATE TABLE/ DROP TABLE 输出作为字符串获取?¶


现代 SQLAlchemy 具有表示 DDL作的子句构造。这些可以像任何其他 SQL 表达式一样呈现为字符串:

from sqlalchemy.schema import CreateTable

print(CreateTable(mytable))


要获取特定于特定引擎的字符串,请执行以下作:

print(CreateTable(mytable).compile(engine))


还有一种特殊形式的 Engine 可通过 create_mock_engine() 允许使用以下配方将整个元数据创建序列转储为字符串:

from sqlalchemy import create_mock_engine


def dump(sql, *multiparams, **params):
    print(sql.compile(dialect=engine.dialect))


engine = create_mock_engine("postgresql+psycopg2://", dump)
metadata_obj.create_all(engine, checkfirst=False)


Alembic 工具还支持“离线”SQL 生成模式,该模式将数据库迁移呈现为 SQL 脚本。


如何子类化 Table/Column 以提供某些行为/配置?¶


Table 和 Column 不是直接子类化的良好目标。但是,有一些简单的方法可以使用创建函数获取构造中行为,以及与架构对象之间的链接相关的行为,例如使用附件事件的约束约定或命名约定。其中许多技术的示例可以在 命名约定 中看到。


Previous: 连接 / 引擎Next: SQL 表达式

© 版权所有 2007-2025,SQLAlchemy 作者和贡献者。


燃烧!龙和炼金术士形象设计由 Rotem Yaari 创作并慷慨捐赠。


使用 Sphinx 7.2.6 创建。 文档上一次生成时间:美国东部标准时间 2025 年 1 月 7 日星期二下午 01:43:01