带有 JOIN 的混合 属性 表达式
Hybrid property expression with JOIN
我是 peewee
的新手,但对 SQLAlchemy(以及随之而来的所有恶习)有一定的了解。我正在尝试创建一个与第三个(甚至 N 个)table 相关的自定义混合表达式。我将尝试在示例(未测试)代码中进行演示:
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
使用 Article
上的 username
hybrid_property
,我可以使用 Article
获得与 Person
相关的 username
PersonTree
作为相关性,到目前为止一切顺利,但是......如果我想 "create a shortcut" 查询由 "john_doe"
Person
用户名创建的所有 Articles
怎么办,我每次进行查询时都没有声明 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';
提前致谢!
混合属性可用于允许将属性表示为模型实例的 属性 或 SQL 查询中的标量计算。
您尝试做的是通过 属性 添加多个连接和内容,使用混合属性是不可能的。
What if I wanted to "create a shortcut" to query all Articles created by the "john_doe" Person username
只需添加一个普通方法:
@classmethod
def by_username(cls, username):
return (Article
.select(Article, PersonTree, Person)
.join(PersonTree)
.join(Person)
.where(Person.name == username))
我是 peewee
的新手,但对 SQLAlchemy(以及随之而来的所有恶习)有一定的了解。我正在尝试创建一个与第三个(甚至 N 个)table 相关的自定义混合表达式。我将尝试在示例(未测试)代码中进行演示:
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
使用 Article
上的 username
hybrid_property
,我可以使用 Article
获得与 Person
相关的 username
PersonTree
作为相关性,到目前为止一切顺利,但是......如果我想 "create a shortcut" 查询由 "john_doe"
Person
用户名创建的所有 Articles
怎么办,我每次进行查询时都没有声明 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';
提前致谢!
混合属性可用于允许将属性表示为模型实例的 属性 或 SQL 查询中的标量计算。
您尝试做的是通过 属性 添加多个连接和内容,使用混合属性是不可能的。
What if I wanted to "create a shortcut" to query all Articles created by the "john_doe" Person username
只需添加一个普通方法:
@classmethod
def by_username(cls, username):
return (Article
.select(Article, PersonTree, Person)
.join(PersonTree)
.join(Person)
.where(Person.name == username))