2012-07-25 12 views
7

Estoy usando SQLAlchemy en un proyecto que no es una aplicación web. Es una aplicación de servidor que carga una cantidad de objetos diferentes de la base de datos y los modifica localmente, pero no desea guardar esas actualizaciones en la base de datos cada vez que se emite una confirmación. Anteriormente estaba trabajando con Django ORM para algunos proyectos web y me pareció más adecuado para lo que estoy tratando de lograr. En Django ORM podía guardar cada objeto cuando quisiera sin guardar otras cosas que no quisiera guardar. Entiendo por qué funciona así en SQLAlchemy, pero me pregunto cómo podría hacerlo a la manera de Django.Deshabilitar el cambio de objeto de commit en SQLAlchemy


Actualización: Para que sea más fácil de entender lo que estoy tratando de lograr, y yo le proporcionaremos un ejemplo.

Ésta es la forma en que funciona realmente:

a = MyModel.query.get(1) 
b = MyModel.query.get(1) 

a.somefield = 1 
b.somefield = 2 

# this will save both of changed models 
session.commit() 

Así es como yo quiero que funcione:

a = MyModel.query.get(1) 
b = MyModel.query.get(1) 

a.somefield = 1 
b.somefield = 2 

a.save() 
# I didn't want to save b, changes of b weren't committed 

Quiero tener un mayor control de lo que realmente está guardado. Quiero guardar los cambios de cada objeto cada 5 minutos más o menos.

+0

¿Has encontrado tu propia solución? Si tiene, por favor, comparta. –

Respuesta

2

Uso algo como:

class BaseModel(object): 
    def save(self, commit=True): 
     # this part can be optimized. 
     try: 
      db.session.add(self) 
     except FlushError: 
      # In case of an update operation. 
      pass 

     if commit: 
      db.session.commit() 

    def delete(self, commit=True): 
     db.session.delete(self) 

     if commit: 
      db.session.commit() 

y luego defino mis modelos como:

class User(db.Model, BaseModel) 

Así que, ahora que puedo hacer:

u = User(username='foo', password='bar') 
u.save() 

Esto es lo que se planea lograr?

2

No estoy seguro de entender su situación.

En Django,

foo = MyModel(field1='value1', field2='value2') 
foo.save() 

o alternativamente

foo = MyModel.objects.create(field1='value1', field2='value2') 

En SQLAlchemy,

foo = MyModel(field1='value1', field2='value2') 
session.add(foo) 

En este punto, sólo se han añadido el objeto de la sesión y no lo ha hecho todavía cometió la transacción. Es necesario para cometer sólo después de haber hecho los cambios que se requerían

session.commit() 

echar un vistazo que esta link. Creo que hará más fácil la transición de Django ORM a SqlAlchemy.

ACTUALIZACIÓN

Por tal situación, se podría utilizar varias sesiones.

engine = create_engine("postgresql+psycopg2://user:[email protected]/test") 
metadata = MetaData(bind=engine) 
Session = sessionmaker(bind=engine) 
session1 = Session() 
session2 = Session() 
Base = declarative_base() 
class User(Base): 
    __tablename__ = 'users' 
    id = Column(Integer, primary_key=True) 
    name = Column(String) 
    age = Column(Integer) 
    def __init__(self, name, age): 
     self.name = name 
     self.age = age 
    def __repr__(self): 
     return "<User('%s','%s')>" % (self.name, self.age) 
Base.metadata.create_all(engine) 

Se creó una tabla 'usuarios' en la 'prueba' db. Además, se han inicializado 2 objetos de sesión, session1 y session2.

a = User('foo','10') 
b = User('bar', '20') 
session1.add(a) 
session1.add(b) 
session1.commit() 

Los usuarios tendrán ahora la tabla 2 registros

1: foo, 10 
2: bar, 20 

Obtención del registro 'foo' cantar session1 y 'bar' usando reunión2.

foo = session1.query(User).filter(User.name == "foo").first() 
bar = session2.query(User).filter(User.name == "bar").first() 

realizar cambios en el 2 registros

foo.age = 11 
bar.age = 21 

Ahora, si desea que los cambios de foo solos para llevar encima,

session1.commit() 

y para la barra,

session2.commit() 
+0

He editado mi pregunta para aclarar lo que intento lograr. – kjagiello

+0

Voy a necesitar una sesión por cada objeto que almaceno en mi aplicación y parece que en mi caso será bastante grande. – kjagiello

0

no remover una entrada antigua, pero

Usted dice:

quiero guardar los cambios de cada objeto de cada 5 minuto más o menos.

Por qué no utilizar un planificador como Celery (utilizo pyramid_celery)

Con esto se puede ahorrar cada objeto cada 5 minutos, es decir, puede agregar un decorador:.

@periodic_task(run_every=crontab(minute="*/5") 
def somefunction(): 
    #your code here 

Este funciona muy bien, especialmente cuando necesita actualizar su base de datos para asegurarse de que esté actualizada (en el caso de que haya muchos usuarios usando su sistema)

Espero que esto ayude a alguien con el, guardando cada 5 minutos parte.

Cuestiones relacionadas