首页 > 解决方案 > 如何使用 SQL Alchemy 以编程方式为 Oracle 创建查询字符串限制记录?

问题描述

给定一个 SQL Alchemy 引擎、模式名、表名和有限数量的要返回的记录;我想生成一个可以在引擎中给出的数据库中使用的查询字符串。

如果我在所有情况下都以相同的方式构造我的 sqlalchemy 查询:

import sqlalchemy

limit=10
schema='schema_name'
table='table_name'

raw_query = (
    sqlalchemy.select([sqlalchemy.text("*")])
    .select_from(
        sqlalchemy.schema.Table(
            table, sqlalchemy.MetaData(), schema=schema
        )
    )
    .limit(limit)
)

我可以使用 SQL Alchemy compile for Snowflake 成功将此查询编译为字符串形式,如下所示:

snow_engine = sqlalchemy.create_engine('snowflake://{user}:{password}@{account}/'))

query = str(
    raw_query.compile(
        snow_engine, compile_kwargs={"literal_binds": True}
    )
)

print(query)

> SELECT * 
FROM schema_name.table_name
 LIMIT 10

但是,当我对 Oracle 尝试相同的操作时,我会丢失架构和表名:

oracle_engine = sqlalchemy.create_engine('oracle+cx_oracle://{user}:{password}@{host}:{port}/?service_name={service_name}')

query = str(
    raw_query.compile(
        oracle_engine, compile_kwargs={"literal_binds": True}
    )
)

print(query)

> SELECT  FROM DUAL 
WHERE ROWNUM <= 10

我可以使用 Oracle 的一个特殊情况来让它工作,如下所示:

raw_query = (
    sqlalchemy.select([sqlalchemy.text("*")])
    .select_from(
        sqlalchemy.schema.Table(
            table, sqlalchemy.MetaData(), schema=schema
        )
    )
)

query = str(
    raw_query.compile(
        snow_engine, compile_kwargs={"literal_binds": True}
    )
)

query += "\nWHERE ROWNUM <= {limit}".format(limit=limit)
print(query)

> SELECT * 
FROM schema_name.table_name
WHERE ROWNUM <= 10

但是没有更隐含的方法来做到这一点吗?

编辑:我正在运行 SQL Alchemy 1.3.8。看起来这个问题在 1.4 中已经解决了。

标签: oraclesqlalchemy

解决方案


这适用于我SQLAlchemy-1.4.3的 Oracle

raw_query = (
    sqlalchemy.select('*',table(table_name, schema=schema_name)).limit(limit)
)

生成的 SQL 语句是

SELECT anon_1.*
FROM (SELECT *
FROM schema_name.table_name) anon_1
WHERE ROWNUM <= 10

这正是LIMITOracle 方言所期望的


推荐阅读