Disabling committing object changes in SQLAlchemy

I'm using SQLAlchemy in project that is not a web application. It is a server application that loads number of different objects from database and modifies them locally, but don't want to save those updates to the database each time a commit is issued. I was previously working with Django ORM for some web projects and found it better suited for what I'm trying to achieve. In Django ORM I could .save() each object whenever I wanted without saving other things I may not want to save. I understand why it works like this in SQLAlchemy, but I wonder how I could do this in the Django-like way?


Update: To make it easier to understand what I'm trying to achieve, I'll provide you an example.

This is how it works actually:

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

This is how I want it to work:

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

I want to have greater control of what is actually saved. I want to save changes of each object every 5 minute or so.


I use something like:

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

and then I define my models as:

class User(db.Model, BaseModel)

So, now I can do:

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

This is what you were planning to achieve ?


I am not sure i understand your predicament.

In Django,

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

or alternatively

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

In SQLAlchemy,

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

At this point you have only added the object to the session and it has not yet committed the transaction. You need to commit only after you have done whatever changes were required

session.commit()

take a look that this link. I think it will make the transition from Django ORM to SqlAlchemy easier.

UPDATE

For such a situation, you could use multiple sessions.

engine = create_engine("postgresql+psycopg2://user:password@localhost/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)

Created a table 'users' in the 'test' db. Also, 2 session objects, session1 and session2, have been initialized.

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

The table users will now have 2 records

1: foo, 10
2: bar, 20

Fetching the 'foo' record sing session1 and 'bar' using session2.

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

Making changes to the 2 records

foo.age = 11
bar.age = 21

Now, if you want the changes of foo alone to carry over,

session1.commit()

and for bar,

session2.commit() 

Not to stir up an old post, but

You say:

I want to save changes of each object every 5 minute or so.

So why not use a scheduler like Celery.(I use pyramid_celery)

With this you can save each object every 5 minutes, ie You can add a decorator:

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

This works great, especially when you need to update your database to make sure it is up to date(in the case that there is many users using your system)

Hope this helps someone with the, saving every 5 minutes part.

链接地址: http://www.djcxy.com/p/61808.html

上一篇: 从Android相机即时加密视频

下一篇: 禁用SQLAlchemy中的提交对象更改