【问题标题】:Flask-SQLAlchemy : Manipulate attribute of a data upon fetchingFlask-SQLAlchemy :在获取时操作数据的属性
【发布时间】:2017-05-08 22:56:33
【问题描述】:

我正在使用以下模型来存储数据。

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    timestamp=db.Column(DateTime(timezone=True), nullable=False)


    def __init__(self, username, timestamp=None):
        self.username = username
        if timestamp is None:
            timestamp =datetime.datetime.now()
        self.timestamp = timestamp

    def __repr__(self):
        return '<User %r>' % self.username

现在,我的问题是:使用

获取数据时
user = User.query.filter_by(username='admin').first()

我了解数据将被提取并转换为User 对象?

总而言之,我想要完成的是,当获取数据时,使用上述查询,自动操作数据。

也就是说,在我的例子中,时间戳是已知的。我将使用 pytz.localize() 来执行此操作。

我试过了:

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    timestamp=db.Column(DateTime(timezone=True), nullable=False)


    def __init__(self, username, timestamp=None):
        self.username = username
        if timestamp is None:
            timestamp =datetime.datetime.now()
        timestamp = pytz.utc.localize(timestamp)
        self.timestamp = timestamp

    def __repr__(self):
        return '<User %r>' % self.username

我认为它是,当对象被初始化时,

if(timestamp is none)
    new entry
    initialize timestamp
make timezone aware     #even if fetched from db
self.timestamp=timestamp`

但是,它不起作用。查询数据时不会调用__init__。可以做什么?

【问题讨论】:

    标签: python python-2.7 flask sqlalchemy flask-sqlalchemy


    【解决方案1】:

    我在 sqlalchemy 文档中发现,当从一行重新创建对象时,它不使用 __init__()。

    见:http://docs.sqlalchemy.org/en/latest/orm/constructors.html

    SQLAlchemy ORM 在重新创建对象时不会调用 __init__ 数据库行。 ORM 的过程有点类似于 Python 标准库的 pickle 模块,调用低级 __new__ 方法,然后直接在实例上悄悄恢复属性 而不是调用 __init__。

    如果您之前需要对加载数据库的实例进行一些设置 它们已经可以使用了,你可以使用 @reconstructor 装饰器来标记 作为 __init__ 的 ORM 对应方法。 SQLAlchemy 将调用它 每次加载或重建其中之一时没有参数的方法 你的实例。这对于重新创建瞬态属性很有用 通常在您的 __init__ 中分配:

    from sqlalchemy import orm
    
    class MyMappedClass(object):
        def __init__(self, data):
            self.data = data
            # we need stuff on all instances, but not in the database.
            self.stuff = []
    
        @orm.reconstructor
        def init_on_load(self):
            self.stuff = []
    

    【讨论】:

    • 哇。这正是我一直在寻找的东西。但我不知道为什么,它不工作。我添加了@orm.reconstructor def init_on_load(self): print "REonstructor Called" self.timestamp = pytz.utc.localize(self.timestamp) 但没有消息被打印出来。
    • 刚刚在我的一个项目(Python 3.4)中对其进行了测试,还添加了一条打印语句并打印了消息。
    • @Stjin 它在机器上不工作。在运行 Ubuntu 的 VM 上进行了尝试,它可以工作。将对其进行更多研究。非常感谢。自2天以来,我一直坚持下去。尝试了很多东西,但我什至没有想到“重建者”这个词。
    • 刚刚通过谷歌搜索偶然发现它:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 2015-10-31
    • 1970-01-01
    • 2017-02-16
    • 2019-11-10
    • 1970-01-01
    • 2020-06-22
    相关资源
    最近更新 更多