вопрос компилятора sqlalchemy - PullRequest
0 голосов
/ 04 июля 2011

У меня есть собственный класс InsertFromSelect, который делает именно то, что говорит его имя. Выходной запрос - именно то, что мне нужно, проблема в том, что я не могу его выполнить.

Класс:

from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import Executable, ClauseElement

class InsertFromSelect( Executable, ClauseElement ):
    def __init__( self, table, select ):
        self.table = table
        self.select = select

@compiles( InsertFromSelect )
def visit_insert_from_select( element, compiler, **kw ):
    return "INSERT INTO %s (%s)" % (
        compiler.process(element.table, asfrom=True),
        compiler.process(element.select)
    )

Запрос:

import proxy.lib.sqlalchemy.compilers.insertFromSelect as ifs
from sqlalchemy import not_, literal_column, String, text
from proxy.database import engine

ifsTest = ifs.InsertFromSelect(
    user_ip_table,
    select(
        [
            user.id,
            ips_table.c.id, literal_column( "'inactive'", String ),
            literal_column( "'"+service_type+"'", String )
        ]
    ).where(
        not_( ips_table.c.id.in_(
            select(
                [user_ip_table.c.ip_id]
            )
        ) )
    ).where(
        ips_table.c.ip_address.in_( validIps )
    )
)

Вывод запроса (print ifsTest):

INSERT INTO user_ip (SELECT 5144, ip.id, 'inactive', 'proxy' 
FROM ip 
WHERE ip.id NOT IN (SELECT user_ip.ip_id 
FROM user_ip) AND ip.ip_address IN (:ip_address_1, :ip_address_2, :ip_address_3, :ip_address_4, :ip_address_5, :ip_address_6))

Я проверил запрос вручную к базе данных (с параметрами на месте, конечно), и он выдает именно то, что мне нужно, но я не могу выполнить его с помощью sqlalchemy.

I've tried:
connection = engine.connect()
res = connection.execute( ifsTest )
connection.close()

.... но ничего не вставлено. Есть идеи, как мне это сделать?

1 Ответ

1 голос
/ 04 июля 2011

, поскольку вы не используете транзакцию, добавьте опцию "autocommit" в вашу конструкцию:

class InsertFromSelect( Executable, ClauseElement ):
    _execution_options = \
        Executable._execution_options.union({'autocommit': True})
    def __init__( self, table, select ):
        self.table = table
        self.select = select

альтернативно назовите это явно:

connection.execution_options(autocommit=True).execute(mystatement)

или используйте транзакцию:

trans = connection.begin()
connection.execute(...)
trans.commit()

фон:

http://www.sqlalchemy.org/docs/core/connections.html#understanding-autocommit

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...