Câu trả lời:
Lấy một đối tượng bằng cách sử dụng hướng dẫn được hiển thị trong tài liệu Flask-SQLAlchemy . Sau khi bạn có đối tượng mà bạn muốn thay đổi, hãy thay đổi đối tượng đó. Sau đó db.session.commit()
,.
Ví dụ:
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 dựa trên SQLAlchemy, vì vậy hãy nhớ kiểm tra Tài liệu SQLAlchemy .
uesd_at = db.Column(db.DateTime)
Tôi chỉ chạy obj.used_at = datetime.datetime.now()
db.session.commit()
Nhưng không đặt giá trị cho trường.
Có một phương thức update
trên đối tượng BaseQuery trong SQLAlchemy, được trả về bởi filter_by
.
admin = User.query.filter_by(username='admin').update(dict(email='my_new_email@example.com')))
db.session.commit()
Lợi thế của việc sử dụng update
hơn thay đổi thực thể đến khi có nhiều đối tượng được cập nhật.
Nếu bạn muốn cấp add_user
quyền cho tất cả các admin
s,
rows_changed = User.query.filter_by(role='admin').update(dict(permission='add_user'))
db.session.commit()
Lưu ý rằng filter_by
lấy các đối số từ khóa (chỉ sử dụng một =
) trái ngược với filter
lấy một biểu thức.
admin
, có thể gây hiểu lầm vì kết quả sẽ là số hàng được cập nhật. Phải không?
User
mục bị ảnh hưởng bởi truy vấn, không phải số lượng người dùng bị ảnh hưởng?
Điều này không hoạt động nếu bạn sửa đổi thuộc tính đã chọn của mô hình. Các thuộc tính đã chọn phải được thay thế để kích hoạt cập nhật:
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
và gán lại nó.
user.data = data
Chỉ cần gán giá trị và cam kết chúng sẽ hoạt động cho tất cả các loại dữ liệu trừ các thuộc tính JSON và Pickled. Vì kiểu ngâm đã được giải thích ở trên, tôi sẽ lưu ý một cách hơi khác nhưng dễ dàng để cập nhật 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
Giả sử mô hình như trên.
user = User("Jon Dove", {"country":"Sri Lanka"})
db.session.add(user)
db.session.flush()
db.session.commit()
Thao tác này sẽ thêm người dùng vào cơ sở dữ liệu MySQL với dữ liệu {"country": "Sri Lanka"}
Việc sửa đổi dữ liệu sẽ bị bỏ qua. Mã của tôi không hoạt động như sau.
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()
Thay vì phải thực hiện công việc khó khăn là sao chép JSON sang một mệnh lệnh mới (không gán nó cho một biến mới như ở trên), mà lẽ ra phải làm việc, tôi đã tìm ra một cách đơn giản để làm điều đó. Có một cách để gắn cờ hệ thống mà JSON đã thay đổi.
Sau đây là mã làm việc.
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()
Điều này hoạt động như một sự quyến rũ. Có một phương pháp khác được đề xuất cùng với phương pháp này ở đây Hy vọng tôi đã giúp được một số.
db.session.merge(user)
thêm mã này đã làm việc cho tôi, FYI.