对于我的特定用例,我需要:
选择*从some_table进入## tmp
SQL服务器构造,并且我需要在语句实际发送到数据库之前在命令行上向用户显示经过完全编译的语句(包括内联参数)。
我使用了以下食谱(针对SQL Server语法进行了一些微调): https://groups.google.com/forum/#!msg/sqlalchemy/O4M6srJYzk0/B8Umq9y08EoJ
虽然它确实起作用,但我无法让它内联显示参数。
这是实际代码:
from sqlalchemy.sql import Select, table, column
from sqlalchemy.ext.compiler import compiles
class SelectInto(Select):
def __init__(self, columns, into, *arg, **kw):
super(SelectInto, self).__init__(columns, *arg, **kw)
self.into = into
@compiles(SelectInto)
def s_into(element, compiler, **kw):
text = compiler.visit_select(element)
text = text.replace('FROM', f'INTO {element.into} \nFROM')
return text
employee = table('employee', column('id'), column('name'))
select_into = SelectInto([employee.c.id, employee.c.name], "##tmp").select_from(employee).where(employee.c.id.in_([1, 3, 6]))
print(select_into.compile(compile_kwargs={'literal_binds': True}).string)
但是,这返回:
SELECT employee.id, employee.name
INTO ##tmp
FROM employee
WHERE employee.id IN (:id_1, :id_2, :id_3)
而不是:
SELECT employee.id, employee.name
INTO ##tmp
FROM employee
WHERE employee.id IN (1, 3, 6)
我花了很多时间试图找出原因,但我却一无所知。该SelectInto类是sqlalchemy Select类的子类,该类编译带有内联文字绑定的语句而没有任何问题。
为什么在这里不起作用?
任何帮助将不胜感激
答案 0 :(得分:0)
在自定义编译器中转发关键字参数:
@compiles(SelectInto)
def s_into(element, compiler, **kw):
text = compiler.visit_select(element, **kw)
text = text.replace('FROM', f'INTO {element.into} \nFROM')
return text
目前visit_select()
看不到literal_binds
参数,因此它默认为编译占位符。