JOIN的混合属性表达式

问题描述 投票:0回答:1

我对peewee相当陌生,但是对SQLAlchemy有一些很深的背景(及其附带的所有缺点)。我正在尝试创建一个与第三个(甚至N个)表相关的自定义混合表达式。我将尝试在一个示例(未经测试)中进行演示:

class BaseModel(Model):
    class Meta:
        database = database


class Person(BaseModel):
    id = PrimaryKeyField(column_name="person_id")
    name = CharField(max_length=255, column_name="person_name")
    username = CharField(max_length=255, column_name="person_username")



class PersonTree(BaseModel):
    id = PrimaryKeyField(column_name="person_tree_id")
    name = CharField(max_length=255, column_name="person_tree_name")
    code = CharField(max_length=255, column_name="person_tree_code")

    person = ForeignKeyField(
        column_name="person_id",
        model=Person,
        field="id",
        backref="tree",
    )


class Article(BaseModel):
    id = PrimaryKeyField(column_name="article_id")
    name = CharField(max_length=255, column_name="article_name")

    branch = ForeignKeyField(
        column_name="person_tree_id",
        model=PersonTree,
        field="id",
        backref="articles",
    )

    @hybrid_property
    def username(self):
        """
        This gives me the possibility to grab the direct username of an article
        """
        return self.branch.person.username

    @username.expression
    def username(cls):
        """
        What if I wanted to do: Article.query().where(Article.username == "john_doe") ?
        """
        pass

使用username上的hybrid_property Article,我可以使用username作为相关性来获得与Person相关的ArticlePersonTree,但到目前为止还不错。 。如果我想“创建快捷方式”来查询由Articles "john_doe"用户名创建的所有Person,而不在每次查询时都声明JOIN,并且不依赖.filter(branch__person__username="john_doe"),该怎么办?我知道SA(在很大程度上)是可行的,但是我发现peewee很难做到这一点。

为了澄清,这是我希望能够构造的SQL:

SELECT
    *
FROM
    article a
    JOIN person_tree pt ON a.person_tree_id = pt.person_tree_id
    JOIN person p ON pt.person_id = p.person_id
WHERE
    p.username = 'john_doe';

非常感谢!

python peewee
1个回答
0
投票

混合属性可用于允许将属性表示为模型实例的属性或SQL查询中的标量计算。

您要执行的操作是通过属性添加多个联接和填充,无法使用混合属性。

如果我想“创建快捷方式”以查询“ john_doe” Person用户名创建的所有文章该怎么办

只需添加常规方法:

@classmethod
def by_username(cls, username):
    return (Article
            .select(Article, PersonTree, Person)
            .join(PersonTree)
            .join(Person)
            .where(Person.name == username))
© www.soinside.com 2019 - 2024. All rights reserved.