SQL Alchemy を使用して一般的な決定木を作成したいと考えています。つまり、各ノードには任意のタイプの 0 個以上の子があり、タスクはツリー ルートを使用して何らかの式を評価することであり、拡張クラスを使用してロジックを子に渡します。
次の基本クラスを定義しました。
from flask_sqlalchemy import Model, SQLAlchemy, DefaultMeta
from abc import ABCMeta, abstractmethod
from sqlalchemy import Column, Integer, String, Date, Boolean, ForeignKey, Text, Float, Unicode
db = SQLAlchemy(model_class=BaseModel)
class BaseModel(Model):
pass
class ModelABCMeta(DefaultMeta, ABCMeta):
pass
class RuleBaseNode(db.Model, metaclass=ModelABCMeta):
"""Generic base class representing a node in a decision tree"""
id = Column(Integer, primary_key=True)
type = Column(String(50))
parent_node_type = Column(Unicode(255), nullable=True)
parent_node_id = Column(Integer, nullable=True)
parent_node = generic_relationship(parent_node_type, parent_node_id)
__mapper_args__ = {
'polymorphic_on': type,
'polymorphic_identity': 'node'
}
@abstractmethod
def eval(self, input) -> bool:
"""Evaluates an input to a boolean"""
pass
問題は、ノードの子の属性を追加する方法です。
通常はrelationship
withを使用しますが、ドキュメントbackref
には何も見つかりませんでした。
私はそのようなプロパティが欲しいです:
class RuleBaseNode(db.Model, metaclass=ModelABCMeta):
...
@property
def sub_nodes():
return ...
これで、次のようなものを実装できると思いますが、抽象クラスのクエリでは機能しないと思います
def get_sub_nodes(session, node):
session.query(RuleBaseNode).filter(RuleBaseNode.parent_node == node).all()