如何在sqlalchemy.FunctionElement中获取关键字参数?

时间:2017-08-10 15:33:02

标签: python python-3.x datetime sqlalchemy

我正在尝试创建一个函数,该函数将生成相当于datetime.utcnow() + timedelta(days=5, minutes=4)的语句。我希望能够像utc_after(days=5, minutes=4)一样调用它。

应与utcnow()类似,SQLAlchemy documentation

这是我到目前为止工作的一个例子(一种方言只是为了简洁):

from sqlalchemy.sql.expression import FunctionElement
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import DateTime

class utc_after(FunctionElement):
    type = DateTime()
    name = 'utc_after'

@compiles(utc_after, 'sqlite')
def sqlite_utc_after(element, compiler, **kwargs):
    days, hours = list(element.clauses)
    return "datetime('now', '+%s day', '+%s hours')" % (days.value, hours.value)

有效。我可以像以下一样使用它:

week_after_submission = db.Column(db.DateTime, default=utc_after(7, 0))

显然这只是最终代码的存根(它需要+/-格式化,分钟,秒等)。

问题是:如何使用FunctionElement中的关键字参数,以便我可以:

next_week = db.Column(db.DateTime, default=utc_after(days=7))

当我指定utc_after(days=7)时,element.clauses为空。 到目前为止,我尝试使用kwargs中的sqlite_utc_after(这些是空的),挖掘element属性,搜索文档中的线索,但没有结果。

1 个答案:

答案 0 :(得分:0)

将关键字参数设置为属性。

from sqlalchemy.sql.functions import GenericFunction
from sqlalchemy.ext.compiler import compiles
from sqlalchemy import Table, Column, String, MetaData

class last_value(GenericFunction):

    def __init__(self, *clauses, ignore_nulls=False, **kwargs):
        self.ignore_nulls = ignore_nulls
        super().__init__(*clauses, **kwargs)


@compiles(last_value)
def visit_last_value(element, compiler, **kwargs):
    clauses = element.clauses
    ignore_nulls = element.ignore_nulls
    ignore_nulls_clause = ' ignore nulls' if ignore_nulls else ''
    return 'last_value(%s%s)' % (compiler.process(clauses), ignore_nulls_clause)


def test_last_value():
    m = MetaData()
    t = Table('test', m, Column('a', String), Column('b', String))
    c = func.last_value(t.c.a, ignore_nulls=True)
    s = select([c])
    assert ' '.join(str(s).split()) == 'SELECT last_value(test.a ignore nulls) AS last_value_1 FROM test'