【发布时间】:2017-03-14 20:57:51
【问题描述】:
我需要使用按位逻辑 AND/OR 编写一些查询,但只有当我使用 oracle 数据库时,才会收到以下错误:
sqlalchemy.exc.DatabaseError: (cx_Oracle.DatabaseError) ORA-01036: 非法变量名称/编号 [SQL: 'SELECT "Cars"."Id", "Cars"."Name", "Cars"."Price" \nFROM "Cars" \nWHERE ("Cars"."Price" & :Price_1) > :param_1'] [参数:{'Price_1': 32768, 'param_1': 0}]
如果我使用 PostgreSql 或 Sqlite,我会收到预期的答案。
create_engine('sqlite:///cars.sqlite3') 好的! create_engine('postgresql+psycopg2://xxx:yyy@localhost:5432/db_sql_alchemy') 好的! create_engine('oracle+cx_oracle://xxx:yyy@localhost:49161/xe') 错误!
select、where 子句、表创建等其他操作在所有 3 个数据库中都按预期工作。
查看错误日志,查询似乎没有正确转换为 oracle 语法。我期待这样的事情:
从“汽车”中选择“汽车”。“ID”,“汽车”。“名称”,“汽车”。“价格” (BitAnd("汽车"."价格", 32768) > 0);
产生错误的操作是:
stm = stm.where(cars.c.Price.op('&')(0x8000) > 0)
我正在使用 Python 2.7.12 和 SQLAlchemy==1.1.2。
【问题讨论】:
-
Oracle 似乎没有
&运算符。请改用BITAND函数。 -
op()泛型按原样呈现。不涉及翻译(iirc)。你得到了你所要求的。 -
感谢您的回答,但我使用的是 sqlalchemy -SQL Expression Language-。我想,对于任何数据库选择,按位运算的语法都是相同的。我想跳过编写原始 sql,因为我需要使用多个数据库。
-
每个数据库的语法都不一样。如果您需要透明地支持多个数据库后端,则需要创建自定义构造并相应地自定义编译。
-
谢谢@univerio。我想我无法理解一些基本概念。当您说“您需要创建自定义构造并相应地自定义编译”时,我需要按照以下步骤操作,因为未定义按位运算符 '&' 并且使用 -meth:
.ColumnOperators.op- 时没有编译具体的数据库?在文档中,运算符 + 是根据 DB 选择编译的。在哪些情况下,我们有针对特定引擎的编译?您能否提供更多关于如何“自定义构造和相应地自定义编译”的详细信息、代码示例、模式
标签: python oracle11g sqlalchemy