Jawaban:
Ambil objek menggunakan tutorial yang ditampilkan di dokumentasi Flask-SQLAlchemy . Setelah Anda memiliki entitas yang ingin Anda ubah, ubah entitas itu sendiri. Kemudian db.session.commit()
,.
Sebagai contoh:
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 didasarkan pada SQLAlchemy, jadi pastikan untuk memeriksa Dokumen SQLAlchemy juga.
uesd_at = db.Column(db.DateTime)
Saya baru saja menjalankan obj.used_at = datetime.datetime.now()
db.session.commit()
Tapi tidak menetapkan nilai ke lapangan.
Ada metode update
pada objek BaseQuery di SQLAlchemy, yang dikembalikan oleh filter_by
.
admin = User.query.filter_by(username='admin').update(dict(email='my_new_email@example.com')))
db.session.commit()
Keuntungan menggunakan update
lebih dari perubahan entitas datang ketika ada banyak objek yang akan diperbarui.
Jika Anda ingin memberikan add_user
izin kepada semua admin
,
rows_changed = User.query.filter_by(role='admin').update(dict(permission='add_user'))
db.session.commit()
Perhatikan bahwa filter_by
mengambil argumen kata kunci (gunakan hanya satu =
) sebagai lawan filter
yang mengambil ekspresi.
admin
, yang mungkin menyesatkan karena hasilnya adalah jumlah baris yang diperbarui. Bukan?
User
item yang terpengaruh oleh kueri, bukan jumlah pengguna yang terpengaruh?
Ini tidak bekerja jika Anda mengubah atribut acar model. Atribut acar harus diganti untuk memicu pembaruan:
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
dan menetapkannya kembali.
user.data = data
Hanya menetapkan nilai dan menerapkannya akan berfungsi untuk semua tipe data kecuali atribut JSON dan Acar. Karena jenis acar dijelaskan di atas, saya akan mencatat cara yang sedikit berbeda tetapi mudah untuk memperbarui 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
Misalkan modelnya seperti di atas.
user = User("Jon Dove", {"country":"Sri Lanka"})
db.session.add(user)
db.session.flush()
db.session.commit()
Ini akan menambahkan pengguna ke dalam database MySQL dengan data {"country": "Sri Lanka"}
Mengubah data akan diabaikan. Kode saya yang tidak berfungsi adalah sebagai berikut.
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()
Alih-alih melalui pekerjaan menyakitkan menyalin JSON ke dict baru (tidak menugaskannya ke variabel baru seperti di atas), yang seharusnya berhasil, saya menemukan cara sederhana untuk melakukannya. Ada cara untuk menandai sistem yang telah diubah JSON.
Berikut ini adalah kode kerja.
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()
Ini bekerja seperti pesona. Ada metode lain yang diusulkan bersama dengan metode ini di sini Harapan saya telah membantu seseorang.
db.session.merge(user)
menambahkan kode ini berhasil untuk saya, FYI.