SqlAlchemy-绑定参数名称冲突

时间:2019-10-02 14:33:08

标签: python sqlalchemy

在编译具有相同绑定参数名称的多个文本子句时遇到问题。

我有自己的子句(MyJoinClause),我为此写了compile函数。问题是,对于相同的参数名称,编译器上下文只能包含一个值,因此无论在最后一次调用compiler.process的哪个查询中,该值都将在结果中限制为 all strong>其他查询。

代替

SELECT * 
FROM ((select * from x where accid = '100') FULL OUTER JOIN (select * from y where accid = '200'))

它将导致:

SELECT * 
FROM ((select * from x where accid = '200') FULL OUTER JOIN (select * from y where accid = '200'))

完整的示例:

from sqlalchemy import text, select
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql import FromClause
from sqlalchemy.sql.base import Executable

class MyJoinClause(Executable, FromClause):
    def __init__(self, main_query, join_to_query):
        self.main_query = main_query
        self.join_to_query = join_to_query


@compiles(MyJoinClause)
def compile_join_using_query(element: MyJoinClause, compiler, **kwargs):
    query_template = "({}) FULL OUTER JOIN ({})"
    # Both queries have bind params with acc_id
    # As we are calling compiler.process, the acc_id bind param values are set on the compiler context
    format_args = [
        compiler.process(element.main_query),
        compiler.process(element.join_to_query)
    ]
    return ('(' + query_template + ')\n').format(*format_args)

q1 = text('select * from x where accid = :acc_id').bindparams(acc_id='100')
q2 = text('select * from y where accid = :acc_id').bindparams(acc_id='200')

final = MyJoinClause(q1, q2)
final = select(['*']).select_from(final)

print(str(final))
# SELECT * 
# FROM ((select * from x where accid = :acc_id) FULL OUTER JOIN (select * from y where accid = :acc_id))

我有什么选择?文本子句是在其他位置创建的,我无法控制其方式(因此,在参数开头添加前缀对我来说不是一个选择)。

谢谢!

0 个答案:

没有答案