在SQLAlchemy中定义“大小写”时避免“分配前使用”问题

时间:2019-06-12 03:06:05

标签: python sqlalchemy flask-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)

因此,每个帖子都会有一个默认的post_time,但是在更新之前,update_time将是NULL
我想要的是主要通过update_time来使发布顺序排序,如果它的update_time字段值不是NULL,否则就按照post_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中的哪个函数?

编辑:
我之所以将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())

0 个答案:

没有答案