Flask-SQLAlchemy无法创建关系 - SAWarning
我使用了fbone来启动这个项目,并且使用了它实现的一个Flask-SQLAlchemy列扩展,叫做DenormalizedText。我明白这个概念和它的工作原理(这不是我的问题),但我对add
方法的实现却得到了奇怪的结果。
DenormalizedText
class DenormalizedText(Mutable, types.TypeDecorator):
"""
Stores denormalized primary keys that can be
accessed as a set.
:param coerce: coercion function that ensures correct
type is returned
:param separator: separator character
"""
impl = types.Text
def __init__(self, coerce=int, separator=" ", **kwargs):
self.coerce = coerce
self.separator = separator
super(DenormalizedText, self).__init__(**kwargs)
def process_bind_param(self, value, dialect):
if value is not None:
items = [str(item).strip() for item in value]
value = self.separator.join(item for item in items if item)
return value
def process_result_value(self, value, dialect):
if not value:
return set()
return set(self.coerce(item) for item in value.split(self.separator))
def copy_value(self, value):
return set(value)
我的类Person
有一个DenormalizedText参数,叫做family
family = Column(DenormalizedText)
这是我的add方法
# just adds each object to the other's family relationship
def add_family(self, person):
self.family.add(person.id)
person.family.add(self.id)
所以这里有一些奇怪的地方:
我有另一个
Person
的关系,做法和这个完全一样,但它是针对另一个类Residence
的。这一切都正常。所以我想了一下,可能是自引用的实现有问题。但fbone在他们提供的User
类中也这样做,而且那是可以的?!所以我写了一个测试……而且它通过了!
在使用这个方法之前的一切都正常。两个
Person
对象都在会话中并且已经提交,我在尝试添加之前仔细检查了“家庭成员”(确保他们已经保存到数据库并且有ID)。- 偶尔我会遇到这个罕见的错误:
SAWarning: The IN-predicate on "persons.id" was invoked with an empty sequence. This results in a contradiction, which nonetheless can be expensive to evaluate. Consider alternative strategies for improved performance.
- 偶尔我会遇到这个罕见的错误:
正如我所说,这在residences
与Person
的关系中工作得很好,但这里是视图和表单处理器中的相关代码,以防万一:
def create_step2_family():
client = Person()
spouse = Person()
spouse_form = PersonalForm()
# default action
try:
client = Person.get_by_id(session['working_client'])
except KeyError:
flash('Please complete this section first.', 'warning')
return redirect(url_for('client.create_step1_personal'))
else:
# spouse form action
if request.method == 'POST' and spouse_form.validate_on_submit():
spouse_form.populate_obj(spouse)
spouse.type_code = SPOUSE
db.session.add(spouse)
db.session.commit()
if Person.get_by_id(spouse.id):
client.add_family(spouse)
db.session.add(client)
db.session.commit()
return render_template('clients/wizard/step2/family.html', active="Create",
client=client, spouse=spouse, spouse_form=spouse_form, active_tab="family")
1 个回答
0
我需要放个假
这个错误提示“SAWarning: 在 'persons.id' 上的 IN 条件被调用时序列为空。这会导致矛盾,但评估这个情况可能会很耗费资源。考虑其他策略以提高性能。
”是因为我在查询一个返回了空结果的列,或者说 persons.id
的列表是空的,因为,嗯,根本没有任何东西被添加。
而且没有任何东西被添加,是因为我忘了在我的添加方法底部加上这几行代码:
def add_family(self, person):
self.family.add(person.id)
person.family.add(self.id)
self.family=set(self.family)
person.family=set(person.family)
我真是一团糟。总之,如果有人能提供更好的解释或改进代码,我就不接受我自己的答案。