2012-07-25 8 views
7

Sto usando SQLAlchemy in un progetto che non è un'applicazione web. È un'applicazione server che carica un numero di oggetti diversi dal database e li modifica localmente, ma non vuole salvare quegli aggiornamenti nel database ogni volta che viene emesso un commit. In precedenza ho lavorato con Django ORM per alcuni progetti web e l'ho trovato più adatto a quello che sto cercando di ottenere. In Django ORM potevo .save() ogni oggetto ogni volta che volevo senza salvare altre cose che potrei non voler salvare. Capisco perché funzioni in questo modo in SQLAlchemy, ma mi chiedo come potrei farlo nel modo simile a Django?Disabilitare le modifiche all'oggetto di commit in SQLAlchemy


Aggiornamento: Per rendere più facile capire quello che sto cercando di realizzare, vi fornirò un esempio.

Questo è come funziona 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() 

Questo è come io voglio farlo funzionare:

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 

voglio avere un maggiore controllo di ciò che è effettivamente salvato. Voglio salvare le modifiche di ogni oggetto ogni 5 minuti circa.

+0

Hai trovato la tua soluzione? Se hai per favore condividilo. –

risposta

2

Io uso qualcosa come:

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

e poi mi definisco i miei modelli come:

class User(db.Model, BaseModel) 

Così, ora che posso fare:

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

Questo è ciò che si stavano progettando di raggiungere?

2

Non sono sicuro di aver capito la tua situazione.

In Django,

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

o in alternativa

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

In SQLAlchemy,

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

A questo punto si hanno aggiunto solo l'oggetto alla sessione e non ha ancora impegnato la transazione. È necessario impegnarsi solo dopo aver fatto tutte le modifiche apportate richiesto

session.commit() 

un'occhiata che questo link. Penso che renderà più facile la transizione da Django ORM a SqlAlchemy.

UPDATE

Per una situazione del genere, è possibile utilizzare più sessioni.

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) 

Creata una tabella 'utenti' nel 'test' db. Inoltre, 2 oggetti di sessione, session1 e session2, sono stati inizializzati.

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

Gli utenti della tabella avranno ora 2 record

1: foo, 10 
2: bar, 20 

Recupero record 'pippo' cantare session1 e 'bar' utilizzando Sessione 2.

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

di apportare modifiche al 2 record

foo.age = 11 
bar.age = 21 

Ora, se si desidera che le modifiche di foo solo di riporto,

session1.commit() 

e per bar,

session2.commit() 
+0

Ho modificato la mia domanda per chiarire cosa sto cercando di ottenere. – kjagiello

+0

Avrò bisogno di una sessione per ogni oggetto che memorizzerò nella mia applicazione e sembra che nel mio caso sarà un overhead piuttosto grande. – kjagiello

0

non sollevare un vecchio post, ma

Tu dici:

voglio salvare le modifiche di ogni oggetto ogni 5 minuti o giù di lì.

Allora perché non utilizzare uno scheduler come Celery (io uso pyramid_celery)

Con questo è possibile salvare ogni oggetto ogni 5 minuti, cioè è possibile aggiungere un decoratore:.

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

Questo Funziona alla grande, specialmente quando devi aggiornare il tuo database per assicurarti che sia aggiornato (nel caso ci siano molti utenti che usano il tuo sistema)

Spero che questo aiuti qualcuno con il, risparmio ogni 5 minuti parte.

Problemi correlati