【发布时间】:2018-05-24 12:53:33
【问题描述】:
我有以下sqlalchemy 类(简体):
class Persons(Base):
__tablename__ = 'm_persons'
birthDate = db.Column(db.Date, nullable=True)
@hybrid_property
def age(self):
bd = self.birthDate
return relativedelta(date.today(), bd).years
@age.expression
def age(cls):
bd = cls.birthDate
return relativedelta(date.today(), bd).years
当我使用该属性将值打印为时
person = Person.query.get(1)
print(person.age)
它正确地打印了人的年龄。现在,当我尝试将该属性用于如下查询时:
Persons.query.filter(Persons.age >= min_age).all()
然后我得到以下错误:
TypeError: relativedelta only diffs datetime/date
我理解为 cls.birthDate 的类型是
class 'sqlalchemy.orm.attributes.InstrumentedAttribute'
那么问题是我缺少什么来获取属性birthDate 的值?
当然,我一直在“谷歌搜索”并阅读了doc,但找不到它不起作用的原因或解决方案。
任何帮助将不胜感激。
*** 编辑 **** 错误的痕迹:
File "/Users/ext334/Dev/python/asocio/app/members/forms.py", line 174, in __init__
self.person.choices = listPersons(gender=subscription.gender, min_age=subscription.min_age, max_age=subscription.max_age)
File "/Users/ext334/Dev/python/asocio/app/members/forms.py", line 31, in listPersons
print(Persons.query.join(Members).filter(Persons.age >= min_age, Persons.age <= max_age, extract('year',Persons.birthDate) >= minBirthYear, extract('year',Persons.birthDate) <= maxBirthYear, Persons.sex == gender).order_by(Members.lastname, Members.firstname))
File "/Users/ext334/Dev/python/venv36/lib/python3.6/site-packages/sqlalchemy/ext/hybrid.py", line 867, in __get__
return self._expr_comparator(owner)
File "/Users/ext334/Dev/python/venv36/lib/python3.6/site-packages/sqlalchemy/ext/hybrid.py", line 1066, in expr_comparator
owner, self.__name__, self, comparator(owner),
File "/Users/ext334/Dev/python/venv36/lib/python3.6/site-packages/sqlalchemy/ext/hybrid.py", line 1055, in _expr
return ExprComparator(cls, expr(cls), self)
File "/Users/ext334/Dev/python/asocio/app/members/models.py", line 235, in age
return relativedelta(date.today(), cls.birthDate).years
File "/Users/ext334/Dev/python/venv36/lib/python3.6/site-packages/dateutil/relativedelta.py", line 102, in __init__
raise TypeError("relativedelta only diffs datetime/date")
TypeError: relativedelta only diffs datetime/date
完整的查询:
Persons.query.join(Members).filter(Persons.age >= min_age, Persons.age <= max_age, extract('year',Persons.birthDate) >= minBirthYear, extract('year',Persons.birthDate) <= maxBirthYear, Persons.sex == gender).order_by(Members.lastname, Members.firstname)
全班 Persons :
class Persons(Base):
"""
Description of a person
"""
__tablename__ = 'm_persons'
user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE', onupdate='CASCADE'))
family_id = db.Column(db.Integer, db.ForeignKey('m_families.id', ondelete='CASCADE', onupdate='CASCADE'))
birthDate = db.Column(db.Date, nullable=True)
sex = db.Column(db.String(1), nullable=False, default='U') # U = unknown, F = Female, M = Male
# return the age in years, not rounded
@hybrid_property
def age(self):
return relativedelta(date.today(), self.birthDate).years
@age.expression
def age(cls):
return relativedelta(date.today(), cls.birthDate).years
【问题讨论】:
-
日期的类型是什么?是 datetime.datetime.date() 或用户定义的东西。您也可以在发出 .all() 之前打印查询以调试原因吗?
-
日期的类型确实是 datetime.date,所以只是正常的日期不幸的是我无法打印查询,因为它崩溃了,但这里的源 Persons.query.join(Members).filter(Persons.age >= min_age, Persons.age = minBirthYear, extract('year',Persons.birthDate)
标签: python properties flask-sqlalchemy hybrid