【问题标题】:Flask-SQLAlchemy Can't Create Relationship - SAWarningFlask-SQLAlchemy 无法创建关系 - SAWarning
【发布时间】:2014-06-15 16:08:57
【问题描述】:

我使用fbone 启动了这个项目,我正在使用它实现一个名为DenormalizedText 的Flask-SQLAlchemy 列扩展。我了解了这个概念以及它是如何工作的(不是我的问题),但是我对 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 有一个名为familyDenormalizedText 参数

family = Column(DenormalizedText)

这是添加方法

# 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)

所以这里有一些奇怪的地方:

  1. 我对@9​​87654330@ 有另一个关系,对另一个名为Residence 的类以完全相同的方式完成。这工作正常。所以我想了一会儿,自引用实现可能存在问题。但是 fbone 使用他们提供的 User 类来做到这一点并且有效?!

  2. 所以我写了一个test... 它通过了!

  3. 使用此方法之前的一切工作正常。两个Person 对象都在会话中并已提交,我在尝试添加之前仔细检查了“家庭成员”(确保它们已保存到数据库并具有 id)。

    1. 偶尔我会收到这个罕见的错误: 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.

就像我说的,这适用于 residencesPerson 的关系,但以下是视图和表单处理程序中的相关代码,以防万一:

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")

【问题讨论】:

    标签: python flask sqlalchemy flask-sqlalchemy


    【解决方案1】:

    我需要一个假期

    错误“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.”是因为我在没有返回任何内容的列上调用查询,或者persons.ids 的列表是空的,因为没有添加任何内容。

    并没有添加任何内容,因为我忘记了 add 方法底部的这些小行:

    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)
    

    我一团糟。无论如何,如果有人可以对代码提供更好的解释或改进,我不会接受我的答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多