簡體   English   中英

在SQLAlchemy中禁用提交對象更改

[英]Disabling committing object changes in SQLAlchemy

我在不是Web應用程序的項目中使用SQLAlchemy。 它是一個服務器應用程序,它從數據庫加載許多不同的對象並在本地修改它們,但是每次發出提交時都不希望將這些更新保存到數據庫中。 我以前和Django ORM合作過一些網絡項目,發現它更適合我想要實現的目標。 在Django ORM中我可以隨時隨地使用.save()每個對象而不保存其他我可能不想保存的東西。 我理解為什么它在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)

在'test'db中創建了一個表'users'。 此外,已初始化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

使用session2獲取'foo'記錄會話session1和'bar'。

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分鍾節省一部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM