Respuestas:
Recupere un objeto usando el tutorial que se muestra en la documentación de Flask-SQLAlchemy . Una vez que tenga la entidad que desea cambiar, cambie la entidad en sí. A continuación, db.session.commit()
.
Por ejemplo:
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 se basa en SQLAlchemy, así que asegúrese de consultar también SQLAlchemy Docs .
uesd_at = db.Column(db.DateTime)
simplemente ejecuto obj.used_at = datetime.datetime.now()
db.session.commit()
Pero no valor establecido en el campo.
Hay un método update
en el objeto BaseQuery en SQLAlchemy, que es devuelto por filter_by
.
admin = User.query.filter_by(username='admin').update(dict(email='my_new_email@example.com')))
db.session.commit()
La ventaja de usar update
sobre el cambio de entidad viene cuando hay muchos objetos para actualizar.
Si quieres dar add_user
permiso a todos los admin
s,
rows_changed = User.query.filter_by(role='admin').update(dict(permission='add_user'))
db.session.commit()
Observe que filter_by
toma argumentos de palabras clave (use solo uno =
) en lugar de lo filter
que toma una expresión.
admin
, lo que puede ser engañoso ya que el resultado será el número de filas actualizadas. ¿No es así?
User
elementos afectados por la consulta, no la cantidad de usuarios afectados?
Esto no funciona si modifica un atributo decapado del modelo. Los atributos en escabeche deben reemplazarse para activar actualizaciones:
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
y reasignarlo.
user.data = data
Simplemente asignar el valor y confirmarlos funcionará para todos los tipos de datos, excepto los atributos JSON y Pickled. Dado que el tipo en escabeche se explica anteriormente, anotaré una forma ligeramente diferente pero fácil de actualizar 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
Digamos que el modelo es como el anterior.
user = User("Jon Dove", {"country":"Sri Lanka"})
db.session.add(user)
db.session.flush()
db.session.commit()
Esto agregará al usuario a la base de datos MySQL con datos {"country": "Sri Lanka"}
Se ignorará la modificación de datos. Mi código que no funcionó es el siguiente.
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()
En lugar de pasar por el doloroso trabajo de copiar el JSON a un nuevo dictado (sin asignarlo a una nueva variable como arriba), que debería haber funcionado, encontré una manera simple de hacerlo. Hay una forma de marcar el sistema de que los JSON han cambiado.
A continuación se muestra el código de trabajo.
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()
Funcionó como por arte de magia. Hay otro método propuesto junto con este método aquí Espero haber ayudado a alguien.
db.session.merge(user)
agregar este código funcionó para mí, FYI.