Как переместить CTE для запроса обновления оракула в sqlalchemy - PullRequest
1 голос
/ 09 мая 2019

Я сталкиваюсь с оракульной ошибкой ORA-00928: missing SELECT keyword с запросом, сгенерированным sqlalchemy.Проблема уже была описана и дана здесь .

Мой запрос выглядит так:

WITH table2 (id) AS (
    SELECT id
    FROM table3
)

UPDATE table SET id=1 
WHERE EXISTS (
    SELECT * 
    FROM table 
    WHERE id IN (SELECT id FROM table2)
)

и генерируется следующим образом:

table2 = session.query(table3.id).cte()
update(table).where(exists().where(table.id.in_(table2))).values(id=1)

Теперь мне интересно, как сказать sqlachemy поместить CTE в предложение WHERE, а не выше UPDATE.

UPDATE table SET id=1 
WHERE EXISTS (
    WITH table2 (id) AS (
        SELECT id
        FROM table3
    )

    SELECT * 
    FROM table 
    WHERE id IN (SELECT id FROM table2)
)

1 Ответ

0 голосов
/ 09 мая 2019

CTE - это хороший способ извлечь встроенное представление из запроса и, тем самым, упростить чтение и обслуживание вашего кода.

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

Во-первых, CTE:

SQL> with tab as
  2    (select deptno from dept
  3     where deptno > 10
  4    )
  5  select e.deptno, count(*)
  6  from emp e join tab t on t.deptno = e.deptno
  7  group by e.deptno;

    DEPTNO   COUNT(*)
---------- ----------
        30          6
        20          5

. Его можно переместить во встроенное представление:

SQL> select e.deptno, count(*)
  2  from emp e join (select deptno from dept
  3                   where deptno > 10
  4                  ) t on t.deptno = e.deptno
  5  group by e.deptno;

    DEPTNO   COUNT(*)
---------- ----------
        30          6
        20          5

Или, используя синтаксис old , где таблицы (в предложении FROM) разделяются запятыми, а объединения выполняются в предложении WHERE (это может показаться знакомым):

SQL> select e.deptno, count(*)
  2  from emp e,
  3      (select deptno from dept
  4       where deptno > 10
  5      ) t
  6  where t.deptno = e.deptno
  7  group by e.deptno;

    DEPTNO   COUNT(*)
---------- ----------
        30          6
        20          5

Это означает, что ваш запрос может выглядеть следующим образом;обратите внимание на комментарий, который показывает положение вашего CTE:

update table set
  id = 1
  where exists (select *
                from table
                where id in (select id 
                             from 
                               (select id from table3)  --> this line is your CTE
                            )
               );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...