简体   繁体   中英

Is there a SqlAlchemy database agnostic FROM_UNIXTIME() function?

Currently I have a query similar to the below in flask sqlalchemy:

from sqlalchemy.sql import func

models = (
  Model.query
  .join(ModelTwo)
  .filter(Model.finish_time >= func.from_unixtime(ModelTwo.start_date))
  .all()
)

This works fine with MySQL which I am running in production, however when I run tests against the method using an in-memory SqlLite database it fails because from_unixtime is not a SqlLite function.

Aside from the running tests on the same database as production as closely as possible issue and the fact that I have two different ways of representing data in the database, is there a database agnostic method in SqlAlchemy for handling the conversion of dates to unix timestamps and vice-versa?

For anyone else interested in this, I found a way to create custom functions in SqlAlchemy based on the SQL dialect being used. As such the below achieves what I need:

from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles


class convert_timestamp_to_date(expression.FunctionElement):
    name = 'convert_timestamp_to_date'


@compiles(convert_timestamp_to_date)
def mysql_convert_timestamp_to_date(element, compiler, **kwargs):
    return 'from_unixtime({})'.format(compiler.process(element.clauses))


@compiles(convert_timestamp_to_date, 'sqlite')
def sqlite_convert_timestamp_to_date(element, compiler, **kwargs):
    return 'datetime({}, "unixepoch")'.format(compiler.process(element.clauses))

The query above can now be re-written as such:

models = (
  Model.query
  .join(ModelTwo)
  .filter(Model.finish_time >= convert_timestamp_to_date(ModelTwo.start_date))
  .all()
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM