首页 > 解决方案 > 在 SQLAlchemy 中定义“案例”时避免“分配前使用”问题

问题描述

我有一个Post这样定义的模型flask-sqlalchemy

from datetime import datetime
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class Post(db.Model):
    __tablename__ = 'post'
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.UnicodeText, nullable=False)
    post_time = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    update_time = db.Column(db.DateTime)

因此,每个帖子都会有一个 default post_time,但直到它被更新为止。 我想要的主要是如果它的字段值不是,则使帖子排序,否则排序,如下所示:update_timeNULL
update_timeupdate_timeNULLpost_time

POST_ORDER = case([(Post.update_time != None, Post.update_time)],
                  else_=Post.post_time)

但是由于我想将其声明POST_ORDER为常量,因此会有一个Using variable before assignment问题。

from datetime import datetime
from sqlalchemy import case
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

# Using variable 'Post' before assignment here
POST_ORDER = case([(Post.update_time != None, Post.update_time)],
                  else_=Post.post_time)

class Post(db.Model):
    __tablename__ = 'post'
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.UnicodeText, nullable=False)
    post_time = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    update_time = db.Column(db.DateTime)

我知道我可以将这个变量声明放在Post类之后,但这只是一种解决方法。如何避免这个问题?我可以使用哪个功能flask-sqlalchemy

编辑:
为什么我想将 as 定义POST_ORDER为常量,否则它将违反DRY原则。这里有一个最小的可重现示例:

class Tag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode(120),
                     unique=True,
                     nullable=False,
                     index=True)


post_tag = db.Table(
    'post_tag',
    db.Column('post_id',
              db.Integer,
              db.ForeignKey('post.id'),
              primary_key=True),
    db.Column('tag_id', db.Integer, db.ForeignKey('tag.id'), primary_key=True))


class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.UnicodeText, nullable=False)
    post_time = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    update_time = db.Column(db.DateTime)
    category_id = db.Column(db.Integer, db.ForeignKey('category.id'))

    # Repeat here
    post_order = case([(update_time != None, update_time)], else_=post_time)

    tags = db.relationship('Tag',
                           secondary=post_tag,
                           backref=db.backref('posts',
                                              lazy='dynamic',
                                              order_by=post_order.desc()),
                           lazy='dynamic',
                           order_by=Tag.name)

class Category(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode(120),
                     unique=True,
                     nullable=False,
                     index=True)

    # Repeat here
    # have to consider the class definition order
    post_order = case([(Post.update_time != None, Post.update_time)],
                      else_=Post.post_time)

    posts = db.relationship('Post',
                            backref='category',
                            lazy='dynamic',
                            order_by=post_order.desc())

标签: pythonsqlalchemyflask-sqlalchemy

解决方案


推荐阅读