元数据/架构

优质
小牛编辑
140浏览
2023-12-01

当我说 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 它会锁定。

解决方案是在发出下拉表之前关闭所有连接:

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)

sqlacalchemy是否支持alter table、create view、create trigger、schema升级功能?

一般的alter支持不直接出现在sqlacalchemy中。对于临时的特殊DDL, DDL 可以使用相关的构造。见 自定义DDL 关于这个问题的讨论。

更全面的选择是使用模式迁移工具,如alembic或sqlachemy migrate;请参见 通过迁移更改数据库对象 以供讨论。

如何根据表对象的依赖关系对其排序?

这是通过 MetaData.sorted_tables 功能:

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

如何以字符串形式获取创建表/删除表输出?

现代的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://', dump)
metadata_obj.create_all(engine, checkfirst=False)

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

我如何子类表/列以提供某些行为/配置?

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