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)
一般ALTER支持不直接出现在SQLAlchemy中。对于特殊的DDL,可以使用DDL
和相关的结构。有关此主题的讨论,请参阅core_ddl
。
更全面的选择是使用模式迁移工具,例如Alembic或SQLAlchemy-Migrate;请参阅Altering Schemas through Migrations以便进行讨论。
这可以通过MetaData.sorted_tables
函数使用:
metadata = MetaData()
# ... add Table objects to metadata
ti = metadata.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
形式,可以让您使用以下配方转储整个元数据创建序列:
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)
Alembic工具还支持“离线”SQL生成模式,可将数据库迁移呈现为SQL脚本。