SQLAlchemy 2.0 文档
元数据/模式¶
当我执行 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 和模式升级功能?¶
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 创建。最后生成文档时间: 2024 年 11 月 8 日星期五上午 8:41:19 EST