Antworten:
Rufen Sie ein Objekt mithilfe des in der Flask-SQLAlchemy-Dokumentation gezeigten Lernprogramms ab . Sobald Sie die Entität haben, die Sie ändern möchten, ändern Sie die Entität selbst. Dann db.session.commit()
.
Beispielsweise:
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 basiert auf SQLAlchemy. Lesen Sie daher auch die SQLAlchemy-Dokumente .
uesd_at = db.Column(db.DateTime)
ich nur ausführen, obj.used_at = datetime.datetime.now()
db.session.commit()
aber kein Wert auf das Feld gesetzt.
update
In SQLAlchemy gibt es eine Methode für das BaseQuery-Objekt, die von zurückgegeben wird filter_by
.
admin = User.query.filter_by(username='admin').update(dict(email='my_new_email@example.com')))
db.session.commit()
Der Vorteil der Verwendung update
gegenüber dem Ändern der Entität ergibt sich, wenn viele Objekte aktualisiert werden müssen.
Wenn Sie add_user
allen admin
s die Erlaubnis geben möchten ,
rows_changed = User.query.filter_by(role='admin').update(dict(permission='add_user'))
db.session.commit()
Beachten Sie, dass filter_by
Schlüsselwortargumente verwendet werden (verwenden Sie nur eines =
), während filter
ein Ausdruck verwendet wird.
admin
, was irreführend sein kann, da das Ergebnis die Anzahl der aktualisierten Zeilen ist. Ist es nicht?
User
Elemente von der Abfrage abrufen kann, nicht die Anzahl der betroffenen Benutzer?
Dies funktioniert nicht, wenn Sie ein ausgewähltes Attribut des Modells ändern. Eingelegte Attribute sollten ersetzt werden, um Aktualisierungen auszulösen:
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
und neu zuweisen.
user.data = data
Das Zuweisen und Festschreiben des Werts funktioniert für alle Datentypen außer den Attributen JSON und Pickled. Da der eingelegte Typ oben erläutert wurde, werde ich eine etwas andere, aber einfache Möglichkeit zum Aktualisieren von JSONs aufzeigen.
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
Angenommen, das Modell ist wie oben.
user = User("Jon Dove", {"country":"Sri Lanka"})
db.session.add(user)
db.session.flush()
db.session.commit()
Dadurch wird der Benutzer mit den Daten {"Land": "Sri Lanka"} zur MySQL-Datenbank hinzugefügt.
Das Ändern von Daten wird ignoriert. Mein Code, der nicht funktioniert hat, lautet wie folgt.
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()
Anstatt die schmerzhafte Arbeit des Kopierens des JSON in ein neues Diktat (ohne es wie oben einer neuen Variablen zuzuweisen) zu durchlaufen, die hätte funktionieren sollen, fand ich einen einfachen Weg, dies zu tun. Es gibt eine Möglichkeit, das von JSONs geänderte System zu kennzeichnen.
Es folgt der Arbeitscode.
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()
Das hat wie ein Zauber gewirkt. Zusammen mit dieser Methode wird hier eine andere Methode vorgeschlagen. Ich hoffe, ich habe jemandem geholfen.
db.session.merge(user)
Das Hinzufügen dieses Codes hat bei mir funktioniert, FYI.