问题:Flask-SQLalchemy更新行的信息
如何更新行的信息?
例如,我想更改ID为5的行的名称列。
回答 0
使用Flask-SQLAlchemy文档中显示的教程来检索对象。拥有要更改的实体后,请更改实体本身。然后,db.session.commit()
。
例如:
admin = User.query.filter_by(username='admin').first()
admin.email = 'my_new_email@example.com'
db.session.commit()
user = User.query.get(5)
user.name = 'New Name'
db.session.commit()
Flask-SQLAlchemy基于SQLAlchemy,因此请务必同时查看SQLAlchemy文档。
回答 1
update
SQLAlchemy中的BaseQuery对象有一个方法,由返回filter_by
。
admin = User.query.filter_by(username='admin').update(dict(email='my_new_email@example.com')))
db.session.commit()
update
当要更新的对象很多时,使用更改实体的优势就来了。
如果您想add_user
授予所有admin
s 权限,
rows_changed = User.query.filter_by(role='admin').update(dict(permission='add_user'))
db.session.commit()
注意,filter_by
使用关键字参数(仅使用一个=
),而不是filter
使用表达式。
回答 2
如果您修改模型的腌制属性,这将不起作用。腌制的属性应被替换以触发更新:
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from pprint import pprint
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqllite:////tmp/users.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True)
data = db.Column(db.PickleType())
def __init__(self, name, data):
self.name = name
self.data = data
def __repr__(self):
return '<User %r>' % self.username
db.create_all()
# Create a user.
bob = User('Bob', {})
db.session.add(bob)
db.session.commit()
# Retrieve the row by its name.
bob = User.query.filter_by(name='Bob').first()
pprint(bob.data) # {}
# Modifying data is ignored.
bob.data['foo'] = 123
db.session.commit()
bob = User.query.filter_by(name='Bob').first()
pprint(bob.data) # {}
# Replacing data is respected.
bob.data = {'bar': 321}
db.session.commit()
bob = User.query.filter_by(name='Bob').first()
pprint(bob.data) # {'bar': 321}
# Modifying data is ignored.
bob.data['moo'] = 789
db.session.commit()
bob = User.query.filter_by(name='Bob').first()
pprint(bob.data) # {'bar': 321}
回答 3
仅分配值并提交它们将适用于除JSON和Pickled属性以外的所有数据类型。由于上面已经解释了腌制类型,因此我将记下更新JSON的方法略有不同但很简单。
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True)
data = db.Column(db.JSON)
def __init__(self, name, data):
self.name = name
self.data = data
假设模型如上。
user = User("Jon Dove", {"country":"Sri Lanka"})
db.session.add(user)
db.session.flush()
db.session.commit()
这会将用户与数据{“ country”:“ Sri Lanka”}一起添加到MySQL数据库中
修改数据将被忽略。我的无效代码如下。
user = User.query().filter(User.name=='Jon Dove')
data = user.data
data["province"] = "south"
user.data = data
db.session.merge(user)
db.session.flush()
db.session.commit()
与其完成将JSON复制到新字典(而不是像上面那样将其分配给新变量)的繁琐工作,我应该找到了一种简单的方法来完成该工作。有一种方法可以标记JSON已更改的系统。
以下是工作代码。
from sqlalchemy.orm.attributes import flag_modified
user = User.query().filter(User.name=='Jon Dove')
data = user.data
data["province"] = "south"
user.data = data
flag_modified(user, "data")
db.session.merge(user)
db.session.flush()
db.session.commit()
这就像一个魅力。这里还建议了另一种方法, 希望对我有帮助。