我正在尝试创建一个函数,该函数将生成相当于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
属性,搜索文档中的线索,但没有结果。
答案 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'