Having gone thru the Datacamp videos I now see where my select to get
columns was unnecessary.
So, I now have code that is practically identical to Mike's post. But it
still errors out:
import tidal
from sqlalchemy import create_engine, Column
from sqlalchemy.dialects import oracle
from sqlalchemy.orm import aliased
from sqlalchemy.orm.session import sessionmaker
from sqlalchemy.orm.query import Query
from sqlalchemy.sql import select
from sqlalchemy.sql.expression import literal, text
from tidal import Jobmst
import sqlalchemy
print(sqlalchemy.__version__)
engine = create_engine('oracle://TIDAL:Password123@WINTIDAL:1521/ORCL', echo
=True)
Session = sessionmaker(bind=engine)
ses = Session()
j2 = aliased(Jobmst, name='j2')
j1 = ses.query(
Jobmst.jobmst_id, Jobmst.jobmst_name,
Jobmst.jobmst_prntid, Jobmst.jobmst_type, literal('1').label('lvl')
).filter(Jobmst.jobmst_prntid == None).cte(recursive=True,name='j1')
j1 = j1.union_all(
ses.query(j2.jobmst_id, j2.jobmst_name,
j2.jobmst_prntid, j2.jobmst_type,
j1.c.lvl + 1
).join(j1, j2.jobmst_prntid == j1.c.jobmst_id
).filter(j2.jobmst_prntid != None)
)
stmt = ses.query(j1).prefix_with(
'SEARCH DEPTH FIRST BY JOBMST_NAME SET DISP_SEQ'
).order_by(text('DISP_SEQ'))
print('=== 1: ===')
print(stmt.statement.compile(dialect=oracle.dialect()))
print('=== 2: ===')
print(stmt.first())
Here is the output:
===
C:\opt\tidalconversion>cd c:\opt\tidalconversion && cmd /C "set
"PYTHONIOENCODING=UTF-8" && set "PYTHONUNBUFFERED=1" &&
C:\opt\python\3.6.5-x64\python.exe
C:\Users\administrator\.vscode\extensions\ms-python.python-2018.3.1\pythonFiles\PythonTools\visualstudio_py_launcher.py
c:\opt\tidalconversion 65251 34806ad9-833a-4524-8cd6-18ca4aa74f14
RedirectOutput,RedirectOutput c:\opt\tidalconversion\jobwalk.py "
1.2.6
=== 1: ===
WITH j1(jobmst_id, jobmst_name, jobmst_prntid, jobmst_type, lvl) AS
(SELECT jobmst.jobmst_id AS jobmst_id, jobmst.jobmst_name AS jobmst_name,
jobmst.jobmst_prntid AS jobmst_prntid, jobmst.jobmst_type AS jobmst_type,
:param_1 AS lvlFROM jobmstWHERE jobmst.jobmst_prntid IS NULL UNION ALL
SELECT j2.jobmst_id AS j2_jobmst_id, j2.jobmst_name AS j2_jobmst_name,
j2.jobmst_prntid AS j2_jobmst_prntid, j2.jobmst_type AS j2_jobmst_type,
j1.lvl + :lvl_1 AS anon_1FROM jobmst j2 JOIN j1 ON j2.jobmst_prntid =
j1.jobmst_idWHERE j2.jobmst_prntid IS NOT NULL) SELECT SEARCH DEPTH FIRST
BY JOBMST_NAME SET DISP_SEQ j1.jobmst_id, j1.jobmst_name, j1.jobmst_prntid,
j1.jobmst_type, j1.lvl
FROM j1 ORDER BY DISP_SEQ
=== 2: ===
2018-04-26 15:03:48,768 INFO sqlalchemy.engine.base.Engine SELECT USER FROM
DUAL
2018-04-26 15:03:48,771 INFO sqlalchemy.engine.base.Engine {}
2018-04-26 15:03:48,780 INFO sqlalchemy.engine.base.Engine SELECT
CAST('test plain returns' AS VARCHAR(60 CHAR)) AS anon_1 FROM DUAL
2018-04-26 15:03:48,780 INFO sqlalchemy.engine.base.Engine {}
2018-04-26 15:03:48,780 INFO sqlalchemy.engine.base.Engine SELECT
CAST('test unicode returns' AS NVARCHAR2(60)) AS anon_1 FROM DUAL
2018-04-26 15:03:48,780 INFO sqlalchemy.engine.base.Engine {}
2018-04-26 15:03:48,780 INFO sqlalchemy.engine.base.Engine select value
from nls_session_parameters where parameter = 'NLS_NUMERIC_CHARACTERS'
2018-04-26 15:03:48,795 INFO sqlalchemy.engine.base.Engine {}
2018-04-26 15:03:48,795 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2018-04-26 15:03:48,812 INFO sqlalchemy.engine.base.Engine WITH
j1(jobmst_id, jobmst_name, jobmst_prntid, jobmst_type, lvl) AS
(SELECT jobmst.jobmst_id AS jobmst_id, jobmst.jobmst_name AS jobmst_name,
jobmst.jobmst_prntid AS jobmst_prntid, jobmst.jobmst_type AS jobmst_type,
:param_1 AS lvl
FROM jobmst
WHERE jobmst.jobmst_prntid IS NULL UNION ALL SELECT j2.jobmst_id AS
j2_jobmst_id, j2.jobmst_name AS j2_jobmst_name, j2.jobmst_prntid AS
j2_jobmst_prntid, j2.jobmst_type AS j2_jobmst_type, j1.lvl + :lvl_1 AS
anon_1
FROM jobmst j2 JOIN j1 ON j2.jobmst_prntid = j1.jobmst_id
WHERE j2.jobmst_prntid IS NOT NULL)
SELECT j1_jobmst_id, j1_jobmst_name, j1_jobmst_prntid, j1_jobmst_type,
j1_lvl
FROM (SELECT SEARCH DEPTH FIRST BY JOBMST_NAME SET DISP_SEQ j1.jobmst_id AS
j1_jobmst_id, j1.jobmst_name AS j1_jobmst_name, j1.jobmst_prntid AS
j1_jobmst_prntid, j1.jobmst_type AS j1_jobmst_type, j1.lvl AS j1_lvl
FROM j1 ORDER BY DISP_SEQ)
WHERE ROWNUM <= :param_2
2018-04-26 15:03:48,822 INFO sqlalchemy.engine.base.Engine {'param_1': '1',
'lvl_1': 1, 'param_2': 1}
Traceback (most recent call last):
File "c:\opt\tidalconversion\jobwalk.py", line 34, in <module>
print(stmt.first())
File "C:\opt\python\3.6.5-x64\lib\site-packages\sqlalchemy\orm\query.py",
line 2789, in first
ret = list(self[0:1])
File "C:\opt\python\3.6.5-x64\lib\site-packages\sqlalchemy\orm\query.py",
line 2581, in __getitem__
return list(res)
File "C:\opt\python\3.6.5-x64\lib\site-packages\sqlalchemy\orm\query.py",
line 2889, in __iter__
return self._execute_and_instances(context)
File "C:\opt\python\3.6.5-x64\lib\site-packages\sqlalchemy\orm\query.py",
line 2912, in _execute_and_instances
result = conn.execute(querycontext.statement, self._params)
File
"C:\opt\python\3.6.5-x64\lib\site-packages\sqlalchemy\engine\base.py", line
948, in execute
return meth(self, multiparams, params)
File
"C:\opt\python\3.6.5-x64\lib\site-packages\sqlalchemy\sql\elements.py",
line 269, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File
"C:\opt\python\3.6.5-x64\lib\site-packages\sqlalchemy\engine\base.py", line
1060, in _execute_clauseelement
compiled_sql, distilled_params
File
"C:\opt\python\3.6.5-x64\lib\site-packages\sqlalchemy\engine\base.py", line
1200, in _execute_context
context)
File
"C:\opt\python\3.6.5-x64\lib\site-packages\sqlalchemy\engine\base.py", line
1413, in _handle_dbapi_exception
exc_info
File
"C:\opt\python\3.6.5-x64\lib\site-packages\sqlalchemy\util\compat.py", line
203, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File
"C:\opt\python\3.6.5-x64\lib\site-packages\sqlalchemy\util\compat.py", line
186, in reraise
raise value.with_traceback(tb)
File
"C:\opt\python\3.6.5-x64\lib\site-packages\sqlalchemy\engine\base.py", line
1193, in _execute_context
context)
File
"C:\opt\python\3.6.5-x64\lib\site-packages\sqlalchemy\engine\default.py",
line 507, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.DatabaseError: (cx_Oracle.DatabaseError) ORA-00923: FROM
keyword not found where expected [SQL: 'WITH j1(jobmst_id, jobmst_name,
jobmst_prntid, jobmst_type, lvl) AS \n(SELECT jobmst.jobmst_id AS
jobmst_id, jobmst.jobmst_name AS jobmst_name, jobmst.jobmst_prntid AS
jobmst_prntid, jobmst.jobmst_type AS jobmst_type, :param_1 AS lvl \nFROM
jobmst \nWHERE jobmst.jobmst_prntid IS NULL UNION ALL SELECT j2.jobmst_id
AS j2_jobmst_id, j2.jobmst_name AS j2_jobmst_name, j2.jobmst_prntid AS
j2_jobmst_prntid, j2.jobmst_type AS j2_jobmst_type, j1.lvl + :lvl_1 AS
anon_1 \nFROM jobmst j2 JOIN j1 ON j2.jobmst_prntid = j1.jobmst_id \nWHERE
j2.jobmst_prntid IS NOT NULL)\n SELECT j1_jobmst_id, j1_jobmst_name,
j1_jobmst_prntid, j1_jobmst_type, j1_lvl \nFROM (SELECT SEARCH DEPTH FIRST
BY JOBMST_NAME SET DISP_SEQ j1.jobmst_id AS j1_jobmst_id, j1.jobmst_name AS
j1_jobmst_name, j1.jobmst_prntid AS j1_jobmst_prntid, j1.jobmst_type AS
j1_jobmst_type, j1.lvl AS j1_lvl \nFROM j1 ORDER BY DISP_SEQ) \nWHERE
ROWNUM <= :param_2'] [parameters: {'param_1': '1', 'lvl_1': 1, 'param_2':
1}] (Background on this error at: http://sqlalche.me/e/4xp6)
C:\opt\tidalconversion>
===
I have to say the output SQL is remarkably similar to my original
(I've cut/pasted and formatted it) - INNER JOIN is same as JOIN. In set
theory it's the intersection - so A join B is same as B join A - difference
from my SQL.
I notice the SEARCH DEPTH FIRST PART is now nested and slightly different
to my original.
*If, I'm reading this correctly, I think in my original, DISP_SEQ would
still be in the resultset. But with the code output from the SQLAlchemy,
that is now hidden. I definitely want to keep that in my output.*
ORA-00923: FROM keyword not found where expected - still not sure why I'm
getting this.
*Can someone help me diagnose why this message is occurring?*
SELECT jobmst.jobmst_id AS jobmst_id,
jobmst.jobmst_name AS jobmst_name,
jobmst.jobmst_prntid AS jobmst_prntid,
jobmst.jobmst_type AS jobmst_type,
:param_1 AS lvl
FROM jobmst
WHERE
jobmst.jobmst_prntid IS NULL
UNION ALL
SELECT j2.jobmst_id AS j2_jobmst_id,
j2.jobmst_name AS j2_jobmst_name,
j2.jobmst_prntid AS j2_jobmst_prntid,
j2.jobmst_type AS j2_jobmst_type,
j1.lvl + :lvl_1 AS anon_1
FROM jobmst j2
JOIN j1 ON j2.jobmst_prntid = j1.jobmst_id
WHERE j2.jobmst_prntid IS NOT NULL)
SELECT
j1_jobmst_id,
j1_jobmst_name,
j1_jobmst_prntid,
j1_jobmst_type,
j1_lvl
FROM (SELECT SEARCH DEPTH FIRST BY JOBMST_NAME SET DISP_SEQ
j1.jobmst_id AS j1_jobmst_id,
j1.jobmst_name AS j1_jobmst_name,
j1.jobmst_prntid AS j1_jobmst_prntid,
j1.jobmst_type AS j1_jobmst_type,
j1.lvl AS j1_lvl
FROM j1 ORDER BY DISP_SEQ)
WHERE ROWNUM <= :param_2
2018-04-26 15:03:48,822 INFO sqlalchemy.engine.base.Engine
{'param_1': '1', 'lvl_1': 1, 'param_2': 1}
WITH J1(JOBMST_ID, JOBMST_NAME, JOBMST_PRNTID, JOBMST_TYPE, LVL) AS (
SELECT JOBMST_ID, JOBMST_NAME, JOBMST_PRNTID, JOBMST_TYPE, 1
FROM TIDAL.JOBMST
WHERE JOBMST_PRNTID IS NULLUNION ALLSELECT J2.JOBMST_ID, J2.JOBMST_NAME,
J2.JOBMST_PRNTID, J2.JOBMST_TYPE, J1.LVL + 1FROM TIDAL.JOBMST J2INNER JOIN J1
ON J2.JOBMST_PRNTID = J1.JOBMST_IDWHERE J2.JOBMST_PRNTID IS NOT NULL)
SEARCH DEPTH FIRST BY JOBMST_NAME SET DISP_SEQSELECT *FROM J1ORDER BY DISP_SEQ
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
http://www.sqlalchemy.org/
To post example code, please provide an MCVE: Minimal, Complete, and Verifiable
Example. See http://stackoverflow.com/help/mcve for a full description.
---
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.