如何更新一行的信息?
例如,我想修改id为5的行的名称列。
使用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文档。
在SQLAlchemy中,filter_by
返回一个BaseQuery对象,该对象有一个方法update
。
num_rows_updated = User.query.filter_by(username='admin').update(dict(email='my_new_email@example.com')))
db.session.commit()
使用 update
来更新实体的优势在于需要更新许多对象时。
如果你想将 add_user
权限赋予所有的 admin
,
rows_changed = User.query.filter_by(role='admin').update(dict(permission='add_user'))
db.session.commit()
请注意filter_by
使用关键字参数(仅使用一个=
),而filter
则采用表达式。
如果你修改了模型的一个已pickle化的属性,这种方法就不起作用了。应该替换pickle化的属性以引发更新:
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}
data
并重新分配它。 - sasuser.data = data
。 - sas只是分配值并提交它们将适用于所有数据类型,但不适用于JSON和Pickled属性。由于上面已经解释了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()
这将把用户添加到MySQL数据库中,数据为{"country":"斯里兰卡"}
修改数据将被忽略。我的代码如下所示,但未能正常工作。
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()
这个方法非常好用。除了这种方法外,还有另一种方法在这里提出here。希望我能帮助到您。
db.session.merge(user)
加入这段代码对我很有帮助,供您参考。 - Jeff Bluemelmodels.py 定义序列化程序
def default(o):
if isinstance(o, (date, datetime)):
return o.isoformat()
def get_model_columns(instance,exclude=[]):
columns=instance.__table__.columns.keys()
columns=list(set(columns)-set(exclude))
return columns
class User(db.Model):
__tablename__='user'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
.......
####
def serializers(self):
cols = get_model_columns(self)
dict_val = {}
for c in cols:
dict_val[c] = getattr(self, c)
return json.loads(json.dumps(dict_val,default=default))
class UpdateUserDetails(Resource):
@auth_token_required
def post(self):
json_data = request.get_json()
user_id = current_user.id
try:
instance = User.query.filter(User.id==user_id)
data=instance.update(dict(json_data))
db.session.commit()
updateddata=instance.first()
msg={"msg":"User details updated successfully","data":updateddata.serializers()}
code=200
except Exception as e:
print(e)
msg = {"msg": "Failed to update the userdetails! please contact your administartor."}
code=500
return msg
update
方法(更新会话外的条目),您必须按照以下步骤查询对象:query = db.session.query(UserModel)
query = query.filter(UserModel.id == user_id)
query.update(user_dumped)
db.session.commit()
class SampleObject(db.Model):
id = db.Column(db.BigInteger, primary_key=True)
name = db.Column(db.String(128), nullable=False)
notes = db.Column(db.Text, nullable=False)
def update(self, update_dictionary: dict):
for col_name in self.__table__.columns.keys():
if col_name in update_dictionary:
setattr(self, col_name, update_dictionary[col_name])
db.session.add(self)
db.session.commit()
然后在路由中你可以这样做
object = SampleObject.query.where(SampleObject.id == id).first()
object.update(update_dictionary=request.get_json())
在 Flask 中更新列
admin = User.query.filter_by(username='admin').first()
admin.email = 'my_new_email@example.com'
admin.save()
解决方案(会话)/ 在Flask_sqlalchemy(数据库)中:
db.session.commit()
uesd_at = db.Column(db.DateTime)
我刚才运行了obj.used_at = datetime.datetime.now()
db.session.commit()
但是没有将值设置到字段中。 - Rukeith