Réponses:
Récupérez un objet à l'aide du didacticiel présenté dans la documentation Flask-SQLAlchemy . Une fois que vous avez l'entité que vous souhaitez modifier, changez l'entité elle-même. Ensuite, db.session.commit()
.
Par exemple:
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 est basé sur SQLAlchemy, alors assurez-vous de consulter également la documentation SQLAlchemy .
uesd_at = db.Column(db.DateTime)
je viens de courir obj.used_at = datetime.datetime.now()
db.session.commit()
mais pas la valeur définie sur le champ.
Il existe une méthode update
sur l'objet BaseQuery dans SQLAlchemy, qui est renvoyée par filter_by
.
admin = User.query.filter_by(username='admin').update(dict(email='my_new_email@example.com')))
db.session.commit()
L'avantage d'utiliser par update
rapport à la modification de l'entité survient lorsqu'il y a de nombreux objets à mettre à jour.
Si vous voulez donner la add_user
permission à tous les admin
s,
rows_changed = User.query.filter_by(role='admin').update(dict(permission='add_user'))
db.session.commit()
Notez que filter_by
prend des arguments de mot-clé (utilisez un seul =
) par opposition à filter
qui prend une expression.
admin
, ce qui peut être trompeur car le résultat sera le nombre de lignes mises à jour. N'est-ce pas?
User
éléments affectés par la requête, pas le nombre d'utilisateurs concernés?
Cela ne fonctionne pas si vous modifiez un attribut décapé du modèle. Les attributs marinés doivent être remplacés pour déclencher des mises à jour:
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
et le réaffecter.
user.data = data
Le simple fait d'attribuer la valeur et de les valider fonctionnera pour tous les types de données à l'exception des attributs JSON et Pickled. Étant donné que le type pickled est expliqué ci-dessus, je noterai un moyen légèrement différent mais facile de mettre à jour les 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
Disons que le modèle est comme ci-dessus.
user = User("Jon Dove", {"country":"Sri Lanka"})
db.session.add(user)
db.session.flush()
db.session.commit()
Cela ajoutera l'utilisateur dans la base de données MySQL avec les données {"country": "Sri Lanka"}
La modification des données sera ignorée. Mon code qui n'a pas fonctionné est le suivant.
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()
Au lieu de passer par le travail pénible de copier le JSON dans un nouveau dict (ne pas l'assigner à une nouvelle variable comme ci-dessus), ce qui aurait dû fonctionner, j'ai trouvé un moyen simple de le faire. Il existe un moyen de signaler au système que les JSON ont changé.
Voici le code de travail.
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()
Cela a fonctionné comme un charme. Il y a une autre méthode proposée avec cette méthode ici J'espère avoir aidé quelqu'un.
db.session.merge(user)
l'ajout de ce code a fonctionné pour moi, FYI.