Python 查找sqlalchemy orm中的根引用
有一个模型具有自引用关系,我想找出引用的根节点/记录,例如在下面的示例中,包可能依赖于另一个包Python 查找sqlalchemy orm中的根引用,python,sqlalchemy,Python,Sqlalchemy,有一个模型具有自引用关系,我想找出引用的根节点/记录,例如在下面的示例中,包可能依赖于另一个包 # myapp.py from flask import Flask from flask_sqlalchemy import SQLAlchemy from sqlalchemy.orm import relationship app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db
# myapp.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import relationship
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)
class Package(db.Model):
__tablename__ = "packages"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True)
dep_on_id = db.Column(db.Integer, db.ForeignKey('packages.id'))
dep_on = relationship('Package', remote_side=[id])
def __init__(self, name):
self.name = name
def __repr__(self):
return '<Package (%r)>' % self.name
遍历树和图形可以在SQL中使用,也可以在SQLAlchemy中完成
def find_root_dep(package):
# The initial step. Find the 1st dependency of the Package passed
# as the argument.
cte = db.session.query(Package).\
filter_by(id=package.dep_on_id).\
cte(recursive=True)
# The iterative step. Find Packages that found packages
# depend on. Iteration stops when the query results in
# an empty set, since no Package has NULL id.
cte = cte.union_all(
db.session.query(Package).
filter_by(id=cte.c.dep_on_id))
# Create an alias for returning an entity object.
result_alias = db.aliased(Package, cte)
# The root depends on nothing.
return db.session.query(result_alias).\
filter_by(dep_on_id=None).\
one_or_none()
如果传递一个根包,您的原始实现将返回None,因此SQL实现直接通过查找第一个依赖项开始,这将导致根包的集合为空。您可能需要设备a来查找根。
def find_root_dep(package):
# The initial step. Find the 1st dependency of the Package passed
# as the argument.
cte = db.session.query(Package).\
filter_by(id=package.dep_on_id).\
cte(recursive=True)
# The iterative step. Find Packages that found packages
# depend on. Iteration stops when the query results in
# an empty set, since no Package has NULL id.
cte = cte.union_all(
db.session.query(Package).
filter_by(id=cte.c.dep_on_id))
# Create an alias for returning an entity object.
result_alias = db.aliased(Package, cte)
# The root depends on nothing.
return db.session.query(result_alias).\
filter_by(dep_on_id=None).\
one_or_none()