Risposte:
Recupera un oggetto utilizzando il tutorial mostrato nella documentazione di Flask-SQLAlchemy . Una volta che hai l'entità che vuoi cambiare, cambia l'entità stessa. Poi, db.session.commit()
.
Per esempio:
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 è basato su SQLAlchemy, quindi assicurati di controllare anche i documenti di SQLAlchemy .
uesd_at = db.Column(db.DateTime)
Ho appena eseguito obj.used_at = datetime.datetime.now()
db.session.commit()
ma non il valore impostato sul campo.
Esiste un metodo update
sull'oggetto BaseQuery in SQLAlchemy, che viene restituito da filter_by
.
admin = User.query.filter_by(username='admin').update(dict(email='my_new_email@example.com')))
db.session.commit()
Il vantaggio di utilizzare update
rispetto alla modifica dell'entità si ha quando ci sono molti oggetti da aggiornare.
Se vuoi dare il add_user
permesso a tutti admin
i,
rows_changed = User.query.filter_by(role='admin').update(dict(permission='add_user'))
db.session.commit()
Si noti che filter_by
accetta argomenti di parole chiave (usane solo uno =
) al contrario di filter
quali accetta un'espressione.
admin
, il che potrebbe essere fuorviante poiché il risultato sarà il numero di righe aggiornate. Non è vero?
User
elementi interessati dalla query, non il numero di utenti interessati?
Questo non funziona se si modifica un attributo decapato del modello. Gli attributi in salamoia devono essere sostituiti per attivare gli aggiornamenti:
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
e riassegnarlo.
user.data = data
La semplice assegnazione del valore e il loro commit funzioneranno per tutti i tipi di dati tranne gli attributi JSON e Pickled. Poiché il tipo in salamoia è spiegato sopra, annoterò un modo leggermente diverso ma semplice per aggiornare i 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
Diciamo che il modello è come sopra.
user = User("Jon Dove", {"country":"Sri Lanka"})
db.session.add(user)
db.session.flush()
db.session.commit()
Questo aggiungerà l'utente al database MySQL con i dati {"country": "Sri Lanka"}
La modifica dei dati verrà ignorata. Il mio codice che non ha funzionato è il seguente.
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()
Invece di passare attraverso il doloroso lavoro di copiare il JSON in un nuovo dict (non assegnarlo a una nuova variabile come sopra), che avrebbe dovuto funzionare, ho trovato un modo semplice per farlo. C'è un modo per contrassegnare il sistema che i JSON sono cambiati.
Di seguito è riportato il codice di lavoro.
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()
Questo ha funzionato come un fascino. C'è un altro metodo proposto insieme a questo metodo qui Spero di aver aiutato qualcuno.
db.session.merge(user)
l'aggiunta di questo codice ha funzionato per me, FYI.