Подтвердить что ты не робот

Как сделать INSERT INTO t1 (SELECT * FROM t2) в SQLAlchemy?

В SQLAlchemy, как мне заполнить или обновить таблицу из инструкции SELECT?

4b9b3361

Ответ 1

SQLalchemy не создает эту конструкцию для вас. Вы можете использовать запрос из текста.

session.execute('INSERT INTO t1 (SELECT * FROM t2)')

EDIT:

Более года спустя, но теперь на sqlalchemy 0.6+ вы можете создать его:

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

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

@compiler.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)
    )

insert = InsertFromSelect(t1, select([t1]).where(t1.c.x>5))
print insert

Выдает:

"INSERT INTO mytable (SELECT mytable.x, mytable.y, mytable.z FROM mytable WHERE mytable.x > :x_1)"

Другой EDIT:

Теперь, 4 года спустя, синтаксис включен в SQLAlchemy 0.9 и backported до 0.8.3; Вы можете создать любой select(), а затем использовать новый метод from_select() объектов Insert:

>>> from sqlalchemy.sql import table, column
>>> t1 = table('t1', column('a'), column('b'))
>>> t2 = table('t2', column('x'), column('y'))
>>> print(t1.insert().from_select(['a', 'b'], t2.select().where(t2.c.y == 5)))
INSERT INTO t1 (a, b) SELECT t2.x, t2.y
FROM t2
WHERE t2.y = :y_1

Дополнительная информация в документах.

Ответ 2

Начиная с 0.8.3, вы можете сделать это прямо в sqlalchemy: Insert.from_select:

sel = select([table1.c.a, table1.c.b]).where(table1.c.c > 5)
ins = table2.insert().from_select(['a', 'b'], sel)

Ответ 3

Как отметил Нолько в комментарии, теперь вы можете избавиться от raw sql: http://www.sqlalchemy.org/docs/core/compiler.html#compiling-sub-elements-of-a-custom-expression-construct

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)
    )

insert = InsertFromSelect(t1, select([t1]).where(t1.c.x>5))
print insert

Выдает:

INSERT INTO mytable (SELECT mytable.x, mytable.y, mytable.z FROM mytable WHERE mytable.x > :x_1)