SQLAlchemy With Clause (CTE) с Insert неправильно компилируется для Oracle

Я пытаюсь сгенерировать следующий надуманный оператор 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())

person Matthew Moisen    schedule 26.08.2017    source источник
comment
Как насчет использования подзапроса вместо CTE? 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.2017
comment
@ lad2025 Это надуманный пример, просто чтобы продемонстрировать, что SQLAlchemy явно не соблюдает синтаксис Oracle.   -  person Matthew Moisen    schedule 27.08.2017
comment
Я не знаю, что такое SQLAlchemy (никогда о нем не слышал). Я сделал быстрый поиск в Google, и я вижу, что это такое. Затем я погуглил SQLAlchemy, выбрал диалект SQL - вам тоже стоит попробовать, может быть, это будет полезно. Непосредственное предположение состоит в том, что вы можете указать, на каком диалекте вы хотите, чтобы SQLAlchemy работал. Или ... вы говорите, что у вас настроен SQLAlchemy для диалекта Oracle, но он просто не использует его правильно?   -  person mathguy    schedule 28.08.2017
comment
@mathguy код пытается выбрать диалект в последней строке...   -  person Antti Haapala    schedule 28.08.2017
comment
@MatthewMoisen, вы должны сообщить о проблеме в систему отслеживания ошибок SQLAlchemy. Кажется, что (еще раз) Oracle CTE является нестандартным stackoverflow.com/q/24008316/918959   -  person Antti Haapala    schedule 28.08.2017
comment
@AnttiHaapala - лол, да, я это вижу. Как я уже сказал, я не знаком с языком, поэтому я не пытался читать код.   -  person mathguy    schedule 28.08.2017
comment
Из черновика 2003 года может показаться, что способ Oracle на самом деле является стандартным: ronsavage.github.io/SQL/sql-2003-2.bnf.html#insert%20statement, но мое прочтение может быть, с большой долей вероятности, неверным, а 2003 год довольно старый (но последнее, что я смог найти). Postgresql, кажется, действительно принимает оба: INSERT ... WITH ... SELECT ... работает так же хорошо.   -  person Ilja Everilä    schedule 05.09.2017
comment
И из документов Postgresql: INSERT соответствует стандарту SQL. , за исключением того, что предложение RETURNING является расширением PostgreSQL, как и возможность использования WITH с INSERT. Кроме того: запрос (оператор SELECT) может также содержать предложение WITH. В таком случае в запросе можно ссылаться на оба набора with_query, но второй имеет приоритет, поскольку он более тесно вложен. Интересно, как обстоят дела с SQL Server.   -  person Ilja Everilä    schedule 05.09.2017