Python 3.x peewee:如何将where子句添加到任何select中?

Python 3.x peewee:如何将where子句添加到任何select中?,python-3.x,peewee,Python 3.x,Peewee,我有这样的模型: class AbstractBaseModel(peewee.Model): uuid = peewee.UUIDField(default=uuid4) is_active = peewee.BooleanField(default=False) is_deleted = peewee.BooleanField(default=False) created_at = peewee.DateTimeField(default=datetime.n

我有这样的模型:

class AbstractBaseModel(peewee.Model):
    uuid = peewee.UUIDField(default=uuid4)
    is_active = peewee.BooleanField(default=False)
    is_deleted = peewee.BooleanField(default=False)
    created_at = peewee.DateTimeField(default=datetime.now)
    updated_at = peewee.DateTimeField(default=datetime.now)
    deleted_at = peewee.DateTimeField(null=True)

    class Meta:
        abstract = True
        indexes = (
            (('is_active', 'is_deleted'), False),
        )
posts = (
    Post
    .visible()
    .select(Post.title)
    .join(UserCTE, on=Post.user == UserCTE.c.id)
    .with_cte(UserCTE)
)
for post in posts:
    print(post.title)
我想:

  • (默认情况下)能够选择
    处于活动状态==True
    处于删除状态==False的行
  • 选择所有行,但只跳过
    处于活动状态
    处于删除状态
    标志

  • 这里有一个答案不是皮维所特有的

    假设上面的(未命名)表是“thing”,那么本质上,您的模型擅长于像
    select*fromthing
    这样的查询

    现在,定义一个相关视图,用于选择某些内容,选择您最喜欢的行子集:

    sqlite> create view thing_v  as
       ...>   select uuid, created_at, updated_at, deleted_at
       ...>   from thing
       ...>   where is_active == True and is_deleted == False;
    

    将模型指向该关系,该关系恰好是一个视图(命名查询)而不是一个表。

    它只是Python。。。将助手方法添加到模型类中。例如,如果我有一个博客帖子的
    Post
    类,我可能会写:

    class Post(Model):
        status = IntegerField()  # 1=live, 2=draft, 3=deleted, e.g.
    
        @classmethod
        def visible(cls):
            return cls.select().where(cls.status == 1)
    
    然后,我可能会有一个所有已发布帖子的列表视图:

    @app.route('/')
    def post_index():
        query = Post.visible().order_by(Post.timestamp.desc())
        return render_template('post_index.html', query=query)
    

    我想给出一个很好的答案。

    对于连接和更复杂的查询,我们可以使用PeeWee功能,如下所示:

    class BaseModel(peewee.Model):
        is_deleted = peewee.BooleanField(default=False, index=True)
    
        @classmethod
        def visible_where_clause(cls):
            return cls.is_deleted == False
    
        @classmethod
        def visible(cls):
            return cls.select().where(cls.visible_where_clause())
    
        @classmethod
        def cte(cls, name=None):
            if name is None:
                name = 'CTE_{}'.format(cls.__name__)
            return cls.visible().cte(name)
    
        class Meta:
            abstract = True
    
    class User(BaseModel):
        username = peewee.CharField(max_length=255, unique=True)
        is_active = peewee.BooleanField(default=True, index=True)
    
        @classmethod
        def visible_where_clause(cls):
            return (
                (super().visible_where_clause()) & (cls.is_active == True)
            )
    
    UserCTE = User.cte()
    
    
    class Post(BaseModel):
        status = peewee.IntegerField()  # 1=live, 2=draft, 3=deleted, e.g.
        user = peewee.ForeignKeyField(User)
        title = peewee.CharField(max_length=255)
    
        @classmethod
        def visible_where_clause(cls):
            return (
                    (super().visible_where_clause()) & (cls.status == 1)
            )
    
    PostCTE = Post.cte()
    
    然后,当我们只需要活动用户的活动帖子时,我们可以这样做:

    class AbstractBaseModel(peewee.Model):
        uuid = peewee.UUIDField(default=uuid4)
        is_active = peewee.BooleanField(default=False)
        is_deleted = peewee.BooleanField(default=False)
        created_at = peewee.DateTimeField(default=datetime.now)
        updated_at = peewee.DateTimeField(default=datetime.now)
        deleted_at = peewee.DateTimeField(null=True)
    
        class Meta:
            abstract = True
            indexes = (
                (('is_active', 'is_deleted'), False),
            )
    
    posts = (
        Post
        .visible()
        .select(Post.title)
        .join(UserCTE, on=Post.user == UserCTE.c.id)
        .with_cte(UserCTE)
    )
    for post in posts:
        print(post.title)
    
    记住


    对于
    CTE
    对象,您必须通过添加
    .c.
    来引用,并通过添加
    .with_CTE()

    在查询结束时添加此
    CTE
    。您知道如何将此应用于联接吗?祝贺您学习了CTE。这个答案肯定会弄乱局面,让通过谷歌来到这里的人感到相当困惑。你没有回答你的实际问题,而是谈论了一些相当高级的功能,写了很多无用的东西,让人不得不费力地去寻找真正的答案。@coleifer那么你能扩展你的答案以提供更灵活的解决方案吗?当您想在联接中使用视图或代理时,如何创建类似于视图或代理的模型?