2012-07-25 4 views
7

Ich verwende SQLAlchemy im Projekt, das keine Webanwendung ist. Es ist eine Serveranwendung, die die Anzahl der verschiedenen Objekte aus der Datenbank lädt und lokal ändert, aber diese Aktualisierungen nicht jedes Mal in der Datenbank speichern möchte, wenn eine Festschreibung erfolgt. Ich habe vorher für einige Webprojekte mit Django ORM gearbeitet und fand es besser geeignet für das, was ich erreichen möchte. In Django ORM konnte ich jedes Objekt speichern(), wann immer ich wollte, ohne andere Dinge zu speichern, die ich nicht speichern möchte. Ich verstehe, warum es so in SQLAlchemy funktioniert, aber ich frage mich, wie ich das auf Django-ähnliche Weise machen könnte?Deaktivieren Commit-Objekt Änderungen in SQLAlchemy


Update: Um es einfacher zu verstehen, was ich versuche zu erreichen, werde ich Ihnen ein Beispiel geben.

Dies ist, wie es tatsächlich funktioniert:

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

Dies ist, wie ich es will arbeiten:

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 

Ich möchte eine größere Kontrolle darüber, was tatsächlich gespeichert wird. Ich möchte Änderungen jedes Objekts alle 5 Minuten oder so speichern.

+0

Haben Sie eine eigene Lösung gefunden? Wenn Sie haben, teilen Sie bitte. –

Antwort

2

Ich benutze etwas wie:

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

und dann definiere ich meine Modelle wie:

class User(db.Model, BaseModel) 

So, jetzt kann ich tun:

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

Dies ist, was Sie erreichen wollten?

2

Ich bin mir nicht sicher, ob ich Ihre missliche Lage verstehe.

In Django,

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

oder alternativ

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

In SQLAlchemy,

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

An dieser Stelle haben Sie hinzugefügt nur das Objekt an die Sitzung, und es hat noch nicht hat die Transaktion begangen. Sie müssen nur begehen, nachdem Sie alle Änderungen vor erforderlich waren

session.commit() 

nehmen, dass dieser link einen Blick getan haben. Ich denke, es wird den Übergang von Django ORM zu SqlAlchemy erleichtern.

UPDATE

Für eine solche Situation, könnte man mehrere Sitzungen verwenden.

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) 

Erstellt eine Tabelle 'Benutzer' in der 'Test' db. Außerdem wurden 2 Sitzungsobjekte, Sitzung1 und Sitzung2, initialisiert.

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

Die Tabelle Benutzer haben nun 2 Datensätze

1: foo, 10 
2: bar, 20 

Fetching die 'foo' record session1 und 'bar' mit session2 singen.

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

Änderungen an den 2 Datensätze

foo.age = 11 
bar.age = 21 

Nun, wenn Sie wollen, dass die Änderungen von foo allein über tragen,

session1.commit() 

und für Bar,

session2.commit() 
+0

Ich habe meine Frage bearbeitet, um zu verdeutlichen, was ich erreichen möchte. – kjagiello

+0

Ich brauche eine Sitzung für jedes Objekt, das ich in meiner Anwendung speichern werde, und es scheint, dass es in meinem Fall einen ziemlich großen Aufwand verursacht. – kjagiello

0

keine alte Post zu stiften, aber

Sie sagen:

Ich möchte Änderungen jeder jeden 5 Minuten Objekt speichern, oder so.

Warum also nicht einen Scheduler wie Celery verwenden (ich benutze pyramid_celery)

Mit diesem können Sie jede speichern alle 5 Minuten Objekt, also Sie einen Dekorateur hinzufügen:.

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

Diese funktioniert hervorragend, besonders wenn Sie Ihre Datenbank aktualisieren müssen, um sicherzustellen, dass sie aktuell ist (falls viele Benutzer Ihr System verwenden)

Ich hoffe, dies hilft jemandem mit dem, Speichern alle 5 Minuten Teil.