2011-07-14 11 views

Respuesta

109

recuperar un objeto usando el tutorial shown in the Flask-SQLAlchemy documentation. Una vez que tenga la entidad que desea cambiar, cambie la entidad misma. Luego, db.session.commit().

Por ejemplo:

admin = User.query.filter_by(username='admin').first() 
admin.email = '[email protected]' 
db.session.commit() 

user = User.query.get(5) 
user.name = 'New Name' 
db.session.commit() 

matraz de SQLAlchemy se basa en SQLAlchemy, así que asegúrese de revisar la SQLAlchemy Docs también.

+1

Gracias Mark. Otra cosa. Lo he visto hacer así 'db.add (usuario)' y luego 'dv.session.commit()'. ¿Por qué ambos funcionan?y cual es la diferencia? – pocorschi

+8

Esto tiene que ver con las diferencias entre objetos transitorios, separados y adjuntos en SQLAlchemy (consulte http://www.sqlalchemy.org/docs/orm/session.html#what-does-the-session-do). Además, lea el comentario de Michael Bayer en la lista de correo (http://groups.google.com/group/sqlalchemy/browse_thread/thread/e38e2aba57aeed92?pli=1) para obtener más información. –

+1

Si todavía está confundido sobre las diferencias después de leer por allí, considere hacer otra pregunta. –

50

Hay un método update en el objeto BaseQuery en SQLAlchemy, que se devuelve por filter_by.

admin = User.query.filter_by(username='admin').update(dict(email='[email protected]'))) 
db.session.commit() 

La ventaja de usar update sobre el cambio de la entidad viene cuando hay muchos objetos que se actualicen.

Si usted quiere 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() 

en cuenta que filter_by toma argumentos de palabra clave (una sola = uso) en contraposición a filter que tiene una expresión.

13

Esto no funciona si modifica un atributo en escabeche del modelo. atributos encurtidos deben ser reemplazados con el fin de desencadenar cambios:

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} 
+1

¿Cuál es el mejor enfoque en tales casos? – kampta

+0

Tendría que copiar 'datos' y reasignarlo. – sas

3

Sólo asignar el valor y comprometiéndose a trabajar para todos los tipos de datos, pero JSON y escabeche atributos. Como el tipo escabechado se explica más arriba, anotaré una manera ligeramente diferente pero fácil de actualizar los 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 añadirá al usuario en la base de datos MySQL con los datos { "país": "Sri Lanka"} serán ignorados

modificar 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() 

lugar de pasar por el doloroso trabajo de copiar el JSON a un nuevo dict (no asignarlo a una nueva variable que el anterior), que debería haber trabajado he encontrado una manera simple de hacer eso. Hay una manera de marcar el sistema que los JSON han cambiado.

siguiente es 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() 

Esto funcionó como un amuleto. Hay otro método propuesto, junto con este método here esperanza he ayudado a alguien.

Cuestiones relacionadas