Query regarding Type Conversions for Model Columns
See original GitHub issueHi,
Request to please help on the below:
I am working to create a admin dashboard using flask admin with oracle database as back end. The Search box on one of the page gives me the below error:
sqlalchemy.exc.DatabaseError: (cx_Oracle.DatabaseError) ORA-00906: missing left parenthesis [SQL: 'SELECT count(:count_2) AS count_1 \nFROM measure \nWHERE lower(CAST(measure.measure_code AS N ARCHAR2)) LIKE lower(:param_1) OR lower(CAST(measure.measure_name AS NVARCHAR2)) LIKE lower(:param_2)'] [parameters: {'param_1': u'%da%', 'count_2': '*', 'param_2': u'%da%'}]
This is the SQL:
('SELECT count(:count_2) AS count_1 \nFROM measure \nWHERE lower(CAST(measure.measure_code AS NVARCHAR2)) LIKE lower(:param_1) OR lower(CAST(measure.measure_name AS NVARCHAR2)) LIKE lower(:param_2)' , {'param_1': u'%da%', 'count_2': '*', 'param_2': u'%da%'})
I tried to run the sql by removing the CAST function and it works fine.
Is there any possibility i can force the Flask Admin not to do type casting for the column in my sql.
Thank you for your help.
Issue Analytics
- State:
- Created 6 years ago
- Comments:5
FYI, this is what the error looks like and how I was searching for it in Google…
ORA-00906: missing left parenthesis in Flask-Admin, SqlAlchemy
The error
DatabaseError: (cx_Oracle.DatabaseError) ORA-00906: missing left parenthesis [SQL: u'SELECT count(:count_2) AS count_1 \nFROM "oracle_table" \nWHERE (lower(CAST("column_name" AS NVARCHAR2)) LIKE lower(:param_1) OR (/*... repeated with more parameters and column names ...*/))'] [parameters: { u'param_2': u'%SEARCH_STRING%', u'count_2': '*'}] (Background on this error at: http://sqlalche.me/e/4xp6)
Meaning
Oracle expects a count for the number of characters for some reason. And the count is inside a set of parenthesis. So after stating VARCHAR or NVARCHAR2 or CHAR, in a CAST call, it wants the character count. So
VARCHAR
should beVARCHAR(60)
for example.Work Around
I found a work around! Replace the calls to
cast
with_safe_cast
that I threw together down below.in
flask-admin/flask_admin/contrib/sqla/view.py ModelView._apply_search
near line 911And somewhere else nearby expose _safe_cast
And here are some related threads that mention similar issues:
https://stackoverflow.com/questions/40342555/sqlalchemy-cast-to-binaryn
Also I tried this, but it did NOT seem to affect how CAST behaves:
https://github.com/Pegase745/sqlalchemy-datatables/issues/31 https://github.com/Pegase745/sqlalchemy-datatables/pull/46/commits/8479f59681c266e4c4dd596fb69631beab35b93e
Another workaround that did NOT work for me was to put the length of the column in the Unicode type parameter.
Another place where casting could happen that might benefit from a similar fix.
https://github.com/alan-eu/flask-admin/commit/d36ebcf23344f01bd33beb961ab48c6af5903604 https://github.com/alan-eu/flask-admin/commit/725d4ba2b7b4485bd148faede7fc4cd1f71369a3
I think the true fix would be to have SqlAlchemy handle
CAST
for the oracle sql compiler properly.In fact, @compiles filter on CAST-expression compiler for Oracle works well:
The workaround and sqlalchemy-cast-to-binaryn given by by @peteristhegreat, helps a lot.