禁用SQLAlchemy中的提交对象更改
我在不是Web应用程序的项目中使用SQLAlchemy。 它是一个服务器应用程序,它从数据库中加载许多不同的对象并在本地修改它们,但不希望每次发出提交时都将这些更新保存到数据库中。 我以前曾在Django ORM中为一些Web项目工作,并发现它更适合我尝试实现的目标。 在Django ORM中,我可以每当需要时将每个对象保存(),而不保存其他我可能不想保存的内容。 我明白为什么它在SQLAlchemy中像这样工作,但我想知道如何以类似Django的方式执行此操作?
更新:为了更容易理解我想要实现的目标,我将为您提供一个示例。
这实际上是如何工作的:
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()
这是我希望它工作的方式:
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
我想更好地控制实际保存的内容。 我想每5分钟左右保存每个对象的更改。
我使用类似于:
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()
然后我将我的模型定义为:
class User(db.Model, BaseModel)
所以,现在我可以做到:
u = User(username='foo', password='bar')
u.save()
这是你计划实现的目标?
我不确定我了解你的困境。
在Django中,
foo = MyModel(field1='value1', field2='value2')
foo.save()
或者可选地
foo = MyModel.objects.create(field1='value1', field2='value2')
在SQLAlchemy中,
foo = MyModel(field1='value1', field2='value2')
session.add(foo)
此时,您只将该对象添加到会话中,但尚未提交该事务。 只有在完成了所需的任何更改后,您才需要提交
session.commit()
看看这个链接。 我认为这会让从Django ORM到SqlAlchemy的转换更容易。
UPDATE
对于这种情况,您可以使用多个会话。
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)
在'测试'数据库中创建一个表'用户'。 另外,2个会话对象session1和session2已经初始化。
a = User('foo','10')
b = User('bar', '20')
session1.add(a)
session1.add(b)
session1.commit()
表格用户现在将有2条记录
1: foo, 10
2: bar, 20
获取'foo'记录使用session2唱会话1和'酒吧'。
foo = session1.query(User).filter(User.name == "foo").first()
bar = session2.query(User).filter(User.name == "bar").first()
对2条记录进行更改
foo.age = 11
bar.age = 21
现在,如果你想让foo单独的变化继续下去,
session1.commit()
和酒吧,
session2.commit()
不要挑起一个旧帖子,但是
你说:
我想每5分钟左右保存每个对象的更改。
那么为什么不使用像Celery这样的调度器(我使用pyramid_celery)
有了这个,你可以每5分钟保存一个对象,也就是说你可以添加一个装饰器:
@periodic_task(run_every=crontab(minute="*/5")
def somefunction():
#your code here
这很好,特别是当你需要更新你的数据库以确保它是最新的(在许多用户使用你的系统的情况下)
希望这可以帮助有人,每5分钟一次保存。
链接地址: http://www.djcxy.com/p/61807.html