版本:1.1.0b2 |发布日期:2016年7月1日

SQLAlchemy 1.1文档

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,架构升级功能?

一般的ALTER支持不直接出现在SQLAlchemy中。对于特殊的DDL,可以使用DDL和相关的结构。关于这个问题的讨论见core_ddl

更全面的选择是使用模式迁移工具,如Alembic或SQLAlchemy-Migrate;请参阅Altering Schemas through Migrations以便进行讨论。

我怎样才能按照它们的依赖顺序对Table对象进行排序呢?

这可以通过MetaData.sorted_tables函数使用:

metadata = MetaData()
# ... add Table objects to metadata
ti = metadata.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的特殊形式,可以让您使用以下配方转储整个元数据创建序列:

def dump(sql, *multiparams, **params):
    print(sql.compile(dialect=engine.dialect))
engine = create_engine('postgresql://', strategy='mock', executor=dump)
metadata.create_all(engine, checkfirst=False)

The Alembic tool also supports an “offline” SQL generation mode that renders database migrations as SQL scripts.

我怎么能子类化表/列提供某些行为/配置?

TableColumn不适合直接子类化。然而,有一些简单的方法可以使用创建函数获取构建上的行为,以及与模式对象之间的关联相关的行为(如约束约定或使用附件事件的命名约定)。命名约定中可以看到许多这些技术的一个例子。