这看起来像是sqlalchmy.orm的错误,但可以验证,但我只是缺少了一些东西。
我有一个表users
和一列team_id
,该列是表teams
的外键。在我的User
类中,我在多个attr上使用了@validates
装饰器,包括team_id
。
class User(Base, UserMixin, db.Model):
__tablename__ = 'users'
@validates('team_id')
def validate_team_id(self, key, value):
assert Team.query.get(value), "invalid 'team_id'"
return value
当然还有一个teams表和Team类。到目前为止一切顺利。
我可以删除一个团队:
foo = Team.query.filter(teamname='foo').first()
db.session.delete(foo)
但是当我尝试执行OR来查询与Team相关的任何内容时:
bar = Team.query.filter(teamname='bar').first()
发生此异常:TypeError: object of type 'NoneType' has no len()
请参见下面的部分回溯。
我将import pdb; pdb.set_trace()
放在validate_team_id
内,所以我知道它仅在第二个查询中被调用,并且value
确实是NoneType,但是为什么呢?会被召唤吗?注释掉validate_team_id
可以消除这种行为。
部分回溯:
~/miniconda3/envs/my_env/lib/python3.7/site-packages/sqlalchemy/orm/util.py in set_(state, value, oldvalue, initiator)
134 def set_(state, value, oldvalue, initiator):
135 if include_backrefs or not detect_is_backref(state, initiator):
--> 136 return validator(state.obj(), key, value)
137 else:
138 return value
/home/jeremy/code/my_project/my_app/models.py in validate_team_id(self, key, value)
411 @validates('team_id')
412 def validate_team_id(self, key, value):
--> 413 assert Team.query.get(value), "invalid 'team_id'"
414 return value
415
~/miniconda3/envs/my_env/lib/python3.7/site-packages/sqlalchemy/orm/query.py in get(self, ident)
921 """
922 return self._get_impl(
--> 923 ident, loading.load_on_pk_identity)
924
925 def _identity_lookup(self, mapper, primary_key_identity,
~/miniconda3/envs/my_env/lib/python3.7/site-packages/sqlalchemy/orm/query.py in _get_impl(self, primary_key_identity, db_load_fn, identity_token)
982 mapper = self._only_full_mapper_zero("get")
983
--> 984 if len(primary_key_identity) != len(mapper.primary_key):
985 raise sa_exc.InvalidRequestError(
986 "Incorrect number of values in identifier to formulate "
TypeError: object of type 'NoneType' has no len()