【问题标题】:Why doesn't flask sql alchemy update an attribute for a record?为什么烧瓶 sql alchemy 不更新记录的属性?
【发布时间】:2016-10-10 20:25:35
【问题描述】:

我有一个如下所示的课程:

class Account(db.Model, flask_login.UserMixin):
    __tablename__ = 'account'
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(75))
    username = db.Column(db.String(50))
    password = db.Column(db.String(250))
    admin = db.Column(db.Boolean)

    def __init__(self, email='', username='', password='', admin=None):
        self.email = email
        self.username = username
        self.password = password
        self.admin = admin

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

当我通过表单创建帐户时,admin 属性将为None。但是当我访问数据库并尝试手动将其设置为True时,属性会更新,但是当我再次访问数据库时,属性是None 超级烦人。

这是我在控制台上执行的:

account = Account.query.get(1)
account.admin = True
db.session.commit()
db.admin ----> True

exit()

#restart again
account = Account.query.get(1)
account.admin ----> None

我做错了什么?

【问题讨论】:

  • get 不需要重新获取记录。当account.adminNone 时,你确定你有一个干净的会话吗?
  • 可以肯定的是,这又是一个拥有多个db 实例的情况,因此Account.query 使用的会话与db.session 不同。

标签: python flask sqlalchemy flask-sqlalchemy


【解决方案1】:

这样做:

account = Account.query.get(1)
account.admin = True
db.session.merge(account)
db.session.commit()

将检测到更改并将其发送到数据库。

您拥有的实例和会话中的对象不一定相同 - 尽管它们代表相同的事物 - 它们不是同一个对象。 在 Flask-SqlAlchemy 中有一个配置 SQLALCHEMY_TRACK_MODIFICATIONS 可以让 sqlalchemy 按您的意愿工作。但这非常昂贵,因为 orm 必须监视对所有实例所做的更改。

希望这会有所帮助!

【讨论】:

  • 不幸的是,这对我不起作用,我一直在寻找一整天都没有运气!请,任何帮助将不胜感激。
  • @danibilel 这在很大程度上取决于您如何设置项目。您可以尝试使用 db.session.refresh(account) 从数据库中获取实例的最新数据。但我不能肯定它会起作用。我认为这是为此提出问题的情况;)
  • 您好,感谢您的建议,我希望我可以提出问题,但由于网站政策,我不能提出问题,这个问题与我的非常相似。虽然我可以正常操作数据库中的数据,但我无法更新 current_user,所以这是一个 flask_login 问题而不是数据库问题,感谢您的帮助!
【解决方案2】:

对对象的更改不会添加到会话中。所以正确的方法是

account = Account.query.get(1)
account.admin = True
db.session.add(account)
db.session.commit()

【讨论】:

  • 为什么要将帐户添加到会话中?它已经存在于数据库中,否则 Account.query.get(1) 将不存在。
  • db.session 不仅用于创建新的数据库记录,即插入查询。对数据库的更新也通过它进行管理。所以上面的update query必须加进去。
  • 我知道 db.session 是做什么的。问题在于您的 db.session.add(account) 将 Account 实例添加到会话中,最后在调用 commit() 时,它将被添加到数据库中。看到这个stackoverflow.com/questions/6699360/…
猜你喜欢
  • 2019-04-27
  • 2020-11-25
  • 1970-01-01
  • 2015-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-07
相关资源
最近更新 更多