Я пытаюсь сгенерировать следующий надуманный оператор DML в SQLAlchemy для базы данных Oracle 12CR1:
INSERT INTO baz (name, qty) WITH bar AS ( SELECT bar.name, bar.qty FROM bar ) SELECT foo.name, bar.qty FROM foo JOIN bar ON foo.name = bar.name
Однако SQLAlchemy, похоже, генерирует его не по порядку, например:
WITH bar AS ( SELECT bar.name, bar.qty FROM bar ) INSERT INTO baz (name, qty) SELECT foo.name, bar.qty FROM foo JOIN bar ON foo.name = bar.name
Выполнение этого не по порядку завершается с ошибкой ORA-00923: FROM keyword not found where expected
.
Моя теория заключается в том, что SQLAlchemy использует синтаксис PostgreSQL, который равен WITH ... INSERT INTO ... SELECT ...
, и не соблюдает синтаксис Oracle, который равен INSERT INTO ... WITH ... SELECT ...
.
Есть ли способ заставить это работать с Oracle или, по крайней мере, способ изменить способ компиляции insert().from_select()
?
Чтобы воспроизвести:
from sqlalchemy import (Table, Column, String, Integer,
MetaData, select, func)
from sqlalchemy.dialects import oracle
metadata = MetaData()
foo = Table('foo', metadata, Column('name', String))
bar = Table('bar', metadata, Column('name', String), Column('qty', Integer))
baz = Table('baz', metadata, Column('name', String), Column('qty', Integer))
with_bar = select([bar.c.name, bar.c.qty]).cte('bar')
sel = select([foo.c.name, with_bar.c.qty])
sel = sel.select_from(
foo.join(with_bar,
foo.c.name == with_bar.c.name
)
)
ins = baz.insert().from_select([baz.c.name, baz.c.qty], sel)
print ins.compile(dialect=oracle.dialect())
INSERT INTO baz (name, qty) SELECT foo.name, bar.qty FROM foo JOIN (SELECT bar.name, bar.qty FROM bar) bar ON foo.name = bar.name
Конечно, вы должны использовать правильный синтаксис sqlalchemy, но результат должен работать на обоих диалектах SQL (Oracle/Postgresql) - person Lukasz Szozda   schedule 27.08.2017INSERT ... WITH ... SELECT ...
работает так же хорошо. - person Ilja Everilä   schedule 05.09.2017