Skip to content

Instantly share code, notes, and snippets.

@peteristhegreat
Created July 23, 2018 19:05
Show Gist options
  • Save peteristhegreat/3becffb0956f9fb84f6200e392a78648 to your computer and use it in GitHub Desktop.
Save peteristhegreat/3becffb0956f9fb84f6200e392a78648 to your computer and use it in GitHub Desktop.
Flask Admin, date field, oracle, primary key, "DatabaseError: (cx_Oracle.DatabaseError) ORA-01861: literal does not match format string"

Oracle requires a TO_DATE or CONVERT call in order to compare a string to a primary key if the primary key is a DATE.

In Flask Admin it was giving me trouble with a

DatabaseError: (cx_Oracle.DatabaseError) ORA-01861: literal does not match format string

Here is the full stack trace:

[2018-07-23 14:55:28,584] ERROR in app: Exception on /admin/mylog/details/ [GET]
Traceback (most recent call last):
  File "./lib/python2.7/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "./lib/python2.7/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "./lib/python2.7/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "./lib/python2.7/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "./lib/python2.7/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "./lib/python2.7/site-packages/flask_admin/base.py", line 69, in inner
    return self._run_view(f, *args, **kwargs)
  File "./lib/python2.7/site-packages/flask_admin/base.py", line 368, in _run_view
    return fn(self, *args, **kwargs)
  File "./lib/python2.7/site-packages/flask_admin/model/base.py", line 2092, in details_view
    model = self.get_one(id)
  File "./lib/python2.7/site-packages/flask_admin/contrib/sqla/view.py", line 1065, in get_one
    return self.session.query(self.model).get(tools.iterdecode(id))
  File "./lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 887, in get
    ident, loading.load_on_pk_identity)
  File "./lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 962, in _get_impl
    return db_load_fn(self, primary_key_identity)
  File "./lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 250, in load_on_pk_identity
    return q.one()
  File "./lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2894, in one
    ret = self.one_or_none()
  File "./lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2864, in one_or_none
    ret = list(self)
  File "./lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2935, in __iter__
    return self._execute_and_instances(context)
  File "./lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2958, in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
  File "./lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 948, in execute
    return meth(self, multiparams, params)
  File "./lib/python2.7/site-packages/sqlalchemy/sql/elements.py", line 269, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "./lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1060, in _execute_clauseelement
    compiled_sql, distilled_params
  File "./lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1200, in _execute_context
    context)
  File "./lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1413, in _handle_dbapi_exception
    exc_info
  File "./lib/python2.7/site-packages/sqlalchemy/util/compat.py", line 203, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "./lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
    context)
  File "./lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 508, in do_execute
    cursor.execute(statement, parameters)

Overriding the get_one call fixes it. Get one is found in: flask_admin/contrib/sqla/view.py

from flask_admin.contrib import sqla
import flask_admin as admin
from .models import MyLog
class LogViewAdmin(sqla.ModelView):
def __init__(self, session):
super(LogViewAdmin, self).__init__(MyLog, session)
# Overriding the member function found in flask_admin/contrib/sqla/view.py
def get_one(self, id):
# """
# Return a single model by its id.
#
# :param id:
# Model id
# """
values = tools.iterdecode(id)
if len(values) > 0:
dt = func.to_date(values[0], 'YYYY-MM-DD HH24:MI:SS')
# dt = func.DATE(values[0])
return self.session.query(self.model).filter(and_(MyLog.date_dt == dt, MyLog.msg_id == values[1])).one()
return self.session.query(self.model).get(values)
from ..database import db
from sqlalchemy.dialects.oracle import VARCHAR2, VARCHAR, CHAR, NUMBER, DATE
from sqlalchemy.sql import func
from sqlalchemy import and_, or_
class MyLog(db.Model):
# __bind_key__ = 'oracle'
__tablename__ = 'MY_LOG'
# __table_args__ = {'extend_existing': True} #{'schema': oracle_schema}
date_dt = db.Column('DATE_DT', DATE, primary_key=True, default=func.now())
msg_id = db.Column('MSG_ID', VARCHAR2(250), db.ForeignKey('OTHER_TABLE.MSG_ID'), primary_key=True)
def __str__(self):
return "Log: " + self.msg_id + " " + self.date_dt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment