Выражение гибридного свойства с JOIN - PullRequest
0 голосов
/ 03 марта 2020

Я довольно новичок в 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 связанный с Article с использованием PersonTree в качестве корреляции, пока все хорошо, но ... Что если я хотел бы "создать ярлык" для запроса всех Articles, созданных "john_doe" Person именем пользователя , не объявляя JOIN s каждый раз, когда я делаю запрос, и не полагаясь на .filter(branch__person__username="john_doe")? Я знаю, что это возможно с SA (в значительной степени), но я нахожу это трудным сделать sh с 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';

Заранее большое спасибо!

1 Ответ

0 голосов
/ 04 марта 2020

Гибридные свойства могут использоваться, чтобы позволить атрибуту быть выраженным как свойство экземпляра модели или как скалярное вычисление в запросе SQL.

То, что вы пытаетесь сделать, это добавить несколько объединений и прочее через свойство, невозможно с помощью гибридных свойств.

Что если бы я хотел "создать ярлык", чтобы запросить все статьи, созданные с помощью имени пользователя john_doe "Person"

Просто добавьте обычный метод:

@classmethod
def by_username(cls, username):
    return (Article
            .select(Article, PersonTree, Person)
            .join(PersonTree)
            .join(Person)
            .where(Person.name == username))
...