私は次の自己参照 (ツリー) ノードを持っており、計算されたプロパティuuid_path
とでフィルター処理/並べ替えを行いたいと考えていname_path
ます。
class Node (db.Model):
id = db.Column (db.Integer, db.Sequence ('node_id_seq'), primary_key=True)
###########################################################################
root_id = db.Column (db.Integer, db.ForeignKey (id, ondelete='CASCADE'),
index=True)
nodes = db.relationship ('Node',
cascade='all, delete-orphan', lazy='dynamic',
primaryjoin='Node.id==Node.root_id',
backref=db.backref ('root', remote_side=id))
###########################################################################
_uuid = db.Column (db.String (36), nullable=False, index=True, unique=True,
name = 'uuid')
_name = db.Column (db.Unicode (256), nullable=False, index=True,
name = 'name')
###########################################################################
@hybrid_property
def uuid (self):
return self._uuid
@hybrid_property
def name (self):
return self._name
@name.setter
def name (self, value):
self._name = value
###########################################################################
def __init__ (self, name, root, mime=None, uuid=None):
self.root = root
self._uuid = uuid if uuid else str (uuid_random ())
self._name = unicode (name) if name is not None else None
def __repr__ (self):
return u'<Node@%x: %s>' % (self.id if self.id else 0, self._name)
###########################################################################
@hybrid_property
def uuid_path (self):
node, path = self, []
while node:
path.insert (0, node.uuid)
node = node.root
return os.path.sep.join (path)
@hybrid_property
def name_path (self):
node, path = self, []
while node:
path.insert (0, node.name)
node = node.root
return os.path.sep.join (path)
###########################################################################
Node
インスタンスを取得して egsubnode
を実行すると、 egsubnode.name_path
が正しく取得されroot/subnode
ます。Node.name_path
しかし、 (フィルタリング/ソートのために)使用しようとすると、SQLAlchemyは文句を言います:
Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with Node.root has an attribute 'name'.
次のようなものを紹介する必要があると確信しています。
class Node (db.Model):
@hybrid_property
def name_path (self):
node, path = self, []
while node:
path.insert (0, node.name)
node = node.root
return os.path.sep.join (path)
@name_path.expression
def name_path (cls):
## Recursive SQL expression??
@name_path.expression
しかし、 (または@uuid_path.expression
)の正しい定義を得るのに苦労しています。ルート ノードから問題のノードまでのパスを提供するように SQL に指示する必要があります。
SQLAlchemy にパス値を繰り返し計算するように指示したため、これが必要な理由がわかりません。ご協力いただきありがとうございます。