在编译具有相同绑定参数名称的多个文本子句时遇到问题。
我有自己的子句(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))
我有什么选择?文本子句是在其他位置创建的,我无法控制其方式(因此,在参数开头添加前缀对我来说不是一个选择)。
谢谢!