首页 > 解决方案 > 使用 SQL Alchemy 表示通用决策树

问题描述

我想使用 SQL Alchemy 创建一个通用决策树。也就是说,每个节点都有零个或多个任意类型的子节点,任务是使用树根计算某个表达式,这将使用扩展类将逻辑传递给子节点。

我定义了以下基类:

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

现在的问题是如何添加节点子节点的属性。

通常,我会使用relationshipwith ,但在文档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()

标签: pythonsqlalchemyflask-sqlalchemydecision-treegeneric-relationship

解决方案


推荐阅读