Python 在SQLAlchemy中截断小时/天/周/月/年

Python 在SQLAlchemy中截断小时/天/周/月/年,python,sql,sqlalchemy,Python,Sql,Sqlalchemy,在适用于所有DBMS(尤其是Postgres和SQLite)的SQLAlchemy中,是否有一种方法可以将datetime截断为小时/天/周/月/年?不是现成的,但是您可以制作一个(我想这与): Postgresql的编译器很简单: @compiles(Trunc, 'postgresql') def compile_trunc_postgresql(element, compiler, **kw): return compiler.process(func.date_trunc(ele

在适用于所有DBMS(尤其是Postgres和SQLite)的SQLAlchemy中,是否有一种方法可以将datetime截断为小时/天/周/月/年?

不是现成的,但是您可以制作一个(我想这与):

Postgresql的编译器很简单:

@compiles(Trunc, 'postgresql')
def compile_trunc_postgresql(element, compiler, **kw):
    return compiler.process(func.date_trunc(element.precision, element.expr))
SQLite版本更复杂,因为没有一个停止的截断解决方案:

_modifiers = {
    'year': ('start of year',),
    'month': ('start of month',),
    # This does not account for locale specific first day of week. 1 day
    # is added so that the 1st day of week won't truncate to previous week.
    # Replace 'weekday 0' with 'weekday 1', if you'd like first day of
    # week to be Monday (in accordance with ISO 8601)
    'week': ('1 day', 'weekday 0', '-7 days', 'start of day'),
    'day': ('start of day',),
}

@compiles(Trunc, 'sqlite')
def compile_trunc_sqlite(element, compiler, **kw):
    precision = element.precision
    expr = element.expr
    modifiers = _modifiers.get(precision)

    if modifiers:
        return compiler.process(func.datetime(expr, *modifiers))

    elif precision == 'hour':
        return compiler.process(func.datetime(
            expr,
            func.strftime('-%M minutes', expr),
            func.strftime('-%f seconds', expr)))

    elif precision == 'minute':
        return compiler.process(func.datetime(
            expr, func.strftime('-%f seconds', expr)))

    elif precision == 'second':
        return compiler.process(func.datetime(
            expr,
            func.strftime('-%f seconds', expr),
            func.strftime('%S seconds', expr)))
SQLite版本不支持Postgresql中可用的所有精度修饰符,如“quarter”,但应该非常有用。用法:

In [16]: for p in ['year', 'month', 'week', 'day', 'hour', 'minute', 'second']:
    ...:     print(engine.execute(select([Trunc(p, func.current_timestamp())])).scalar())
    ...:     
2018-01-01 00:00:00
2018-08-01 00:00:00
2018-07-29 00:00:00
2018-08-03 00:00:00
2018-08-03 06:00:00
2018-08-03 06:18:00
2018-08-03 06:18:18

不是现成的,但您可以制作一个(我想这与):

Postgresql的编译器很简单:

@compiles(Trunc, 'postgresql')
def compile_trunc_postgresql(element, compiler, **kw):
    return compiler.process(func.date_trunc(element.precision, element.expr))
SQLite版本更复杂,因为没有一站式的截断解决方案:

_modifiers = {
    'year': ('start of year',),
    'month': ('start of month',),
    # This does not account for locale specific first day of week. 1 day
    # is added so that the 1st day of week won't truncate to previous week.
    # Replace 'weekday 0' with 'weekday 1', if you'd like first day of
    # week to be Monday (in accordance with ISO 8601)
    'week': ('1 day', 'weekday 0', '-7 days', 'start of day'),
    'day': ('start of day',),
}

@compiles(Trunc, 'sqlite')
def compile_trunc_sqlite(element, compiler, **kw):
    precision = element.precision
    expr = element.expr
    modifiers = _modifiers.get(precision)

    if modifiers:
        return compiler.process(func.datetime(expr, *modifiers))

    elif precision == 'hour':
        return compiler.process(func.datetime(
            expr,
            func.strftime('-%M minutes', expr),
            func.strftime('-%f seconds', expr)))

    elif precision == 'minute':
        return compiler.process(func.datetime(
            expr, func.strftime('-%f seconds', expr)))

    elif precision == 'second':
        return compiler.process(func.datetime(
            expr,
            func.strftime('-%f seconds', expr),
            func.strftime('%S seconds', expr)))
SQLite版本不支持Postgresql中可用的所有精度修饰符,如“quarter”,但应该非常有用。用法:

In [16]: for p in ['year', 'month', 'week', 'day', 'hour', 'minute', 'second']:
    ...:     print(engine.execute(select([Trunc(p, func.current_timestamp())])).scalar())
    ...:     
2018-01-01 00:00:00
2018-08-01 00:00:00
2018-07-29 00:00:00
2018-08-03 00:00:00
2018-08-03 06:00:00
2018-08-03 06:18:00
2018-08-03 06:18:18

我还有一个问题。使用Trunc类的查询不会转换为
子查询
。你知道我该如何修复它吗?是的,匆忙地编写并使用了错误的基类。应该是
ColumnElement
。我还有一个问题。使用Trunc类的查询不会转换为
子查询
。你知道我该如何修复它吗?是的,匆忙地编写并使用了错误的基类。应该是
ColumnElement