【问题标题】:aiopg + sqlalchemy: how to "drop table if exists" without raw sql?aiopg + sqlalchemy:如何在没有原始 sql 的情况下“删除表(如果存在)”?
【发布时间】:2020-03-15 23:50:11
【问题描述】:

我在看examples of aiopg usage with sqlalchemy,这些台词吓到我了:

async def create_table(conn):
    await conn.execute('DROP TABLE IF EXISTS tbl')
    await conn.execute(CreateTable(tbl))

我不想在使用 sqlalchemy 时执行原始 sql 查询。但是我找不到任何其他方法来实现相同的逻辑。我的尝试是:

1)

await conn.execute(tbl.drop(checkfirst=True))

这引发了:

sqlalchemy.exc.UnboundExecutionError: 表对象 'tbl' 不是 绑定到引擎或连接。没有 a 就无法执行 要执行的数据库。

我也找不到将表绑定到引擎的方法,因为aiopg doesn't support metadata.create_all

2)

await conn.execute(DropTable(tbl))

这引发了:

psycopg2.errors.UndefinedTable:表“tbl”不存在

似乎DropTable 构造无论如何都不支持IF EXISTS 部分。

所以,问题是,在使用 aiopg + sqlalchemy 时,有没有办法将 await conn.execute('DROP TABLE IF EXISTS tbl') 语句重写为没有原始 sql 的东西?

【问题讨论】:

  • 通常Table.drop() 接受可选的绑定作为第一个位置参数,所以你会像tbl.drop(conn, checkfirst=True) 一样传递conn,但我不知道异步是否支持。顺便说一句。在使用 SQLAlchemy 时执行实际的 SQL 没有错,它甚至提供了一些帮助,例如 text()
  • 抓到UndefinedTable有什么问题?
  • @AndreaCorbellini 执行此查询将需要 4 行(尝试、执行、除外、通过),甚至比使用原始 sql 还要糟糕。我正在寻找最好的(最短,最 Pythonic)的方式来做到这一点。我希望 sqlalchemy 能够为此类简单查询提供内置功能。

标签: python postgresql sqlalchemy drop-table aiopg


【解决方案1】:

这个问题是在最新版本是 SQLAlchemy 1.3.11 时发布的。

从 SQLAlchemy 1.4.0 开始,DropTable 支持 if_exists=True

await conn.execute(DropTable(tbl, if_exists=True))

参考:https://docs.sqlalchemy.org/en/14/core/ddl.html#sqlalchemy.schema.DropTable

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-04
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 2015-05-26
    • 2020-02-09
    相关资源
    最近更新 更多