sqlalchemy'SELECT * INTO ## temptable'配方无法使用文字绑定进行编译

时间:2018-11-07 22:45:36

标签: python sql sqlalchemy

对于我的特定用例,我需要:

选择*从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类的子类,该类编译带有内联文字绑定的语句而没有任何问题。

为什么在这里不起作用?

任何帮助将不胜感激

1 个答案:

答案 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参数,因此它默认为编译占位符。