我尝试使用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
...
我绝对不是嵌套套件的专家,但据我了解,"添加"需要一些前期工作才能找出" left"和"对"既可以添加新项目,也可以添加表格中的所有项目。 (同样地,对于删除。)我想也许我可以在我的应用程序中的常规流程中添加该前期工作,而不是使用示例中的before_insert
。
我一直在查找是否有办法以类似方式覆盖Flask-SQLAlchemy框架内的db.session.add
。或者我应该在这里做些什么?
答案 0 :(得分:0)
我最终实现了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