SQLAlchemy 2.0 文档
MetaData / Schema¶
当我说 table.drop()
/ metadata.drop_all()
时,我的程序挂起了¶
这通常对应于两种情况:1. 使用 PostgreSQL,它对表锁非常严格;2. 您仍然有一个连接处于打开状态,该连接包含表上的锁,并且与用于 DROP 语句的连接不同。 这是模式的最简化版本
connection = engine.connect()
result = connection.execute(mytable.select())
mytable.drop(engine)
上面,连接池连接仍然被检出;此外,上面的结果对象还维护到此连接的链接。 如果使用“隐式执行”,则结果将保持此连接打开,直到结果对象关闭或所有行都用尽。
调用 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 升级功能?¶
SQLAlchemy 中没有直接提供通用的 ALTER 支持。 对于临时的特殊 DDL,可以使用 DDL
和相关构造。 有关此主题的讨论,请参阅 自定义 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
不是直接子类化的好目标。 但是,有一些简单的方法可以使用创建函数来获得构造时的行为,以及使用附件事件获得与模式对象(例如约束约定或命名约定)之间链接相关的行为。 许多这些技术的示例可以在 命名约定 中看到。
flambé! 龙和 炼金术士 图像设计由 Rotem Yaari 创建并慷慨捐赠。
使用 Sphinx 7.2.6 创建。 文档最后生成时间:2025 年 3 月 11 日星期二下午 02:40:17 EDT