【问题标题】:Performing tasks before insert, remove, etc. in flask-sqlalchemy在 flask-sqlalchemy 中插入、删除等之前执行任务
【发布时间】:2014-12-24 18:52:15
【问题描述】:

我正在尝试使用 Flask-SQLAlchemy 实现嵌套集模型。

我看到这个使用 SQLAlchemy 的例子:http://docs.sqlalchemy.org/en/rel_0_9/_modules/examples/nested_sets/nested_sets.html

魔法似乎发生在他们对before_insert的定义中:

@event.listens_for(Employee, "before_insert")
def before_insert(mapper, connection, instance):
    if not instance.parent:
        instance.left = 1
...

我绝对不是嵌套集合方面的专家,但据我了解,“添加”需要一些前期工作才能为要添加的新项目找出“左”和“右”的新值,以及可能用于表中的所有内容。 (同样适用于删除。)我想也许我可以在我的应用程序的常规流程中添加该预工作,而不是使用示例中的 before_insert

我一直在寻找是否有办法以类似的方式从 Flask-SQLAlchemy 框架中覆盖 db.session.add。还是我应该在这里做点别的?

【问题讨论】:

标签: python sqlalchemy flask-sqlalchemy nested-sets


【解决方案1】:

我最终实现了nested intervals(而不是嵌套集)。希望对大家有帮助!

class Employee(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    employee_name = db.Column(db.String(120))
    parent = db.Column(db.Integer, db.ForeignKey('employee.id'), index=True)
    # implements nested intervals with fractions
    created = db.Column(db.DateTime, index=True)
    left_num = db.Column(db.Integer, nullable=False)
    left_den = db.Column(db.Integer, nullable=False)
    right_num = db.Column(db.Integer, nullable=False)
    right_den = db.Column(db.Integer, nullable=False)
    level = db.Column(db.Integer, nullable=False)

    def __init__(self, employee_name, parent):
        self.created = datetime.datetime.now()
        self.employee_name = employee_name
        self.parent = parent

        # handle case of first addition
        if not parent:
            self.level = 1
            left_node_num = 0
            left_node_den = 1
            right_node_num = 1
            right_node_den = 1
        else:
            parent_employee = Employee.query.get(self.parent)
            # if the parent exists, set level to 1 more
            self.level = parent_employee.level + 1
            # find the most recent sibling
            most_recent_sibling = Employee.query\
                .filter_by(parent=self.parent)\
                .order_by(Employee.id.desc())\
                .first()
            if not most_recent_sibling:
                # if no sibling, use parent boundaries
                left_node_num = parent_employee.left_num
                left_node_den = parent_employee.left_den
            else:
                left_node_num = most_recent_sibling.right_num
                left_node_den = most_recent_sibling.right_den
            right_node_num = parent_employee.right_num
            right_node_den = parent_employee.right_den
        left_boundary = fractions.Fraction(numerator=left_node_num + right_node_num,
                                           denominator=left_node_den + right_node_den)
        right_boundary = fractions.Fraction(numerator=left_boundary.numerator + right_node_num,
                                            denominator=left_boundary.denominator + right_node_den)
        self.left_num = left_boundary.numerator
        self.left_den = left_boundary.denominator
        self.right_num = right_boundary.numerator
        self.right_den = right_boundary.denominator

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-16
    • 2016-01-11
    • 2020-05-08
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 2011-04-11
    • 2016-07-12
    相关资源
    最近更新 更多