8

Web アプリケーションではないプロジェクトで SQLAlchemy を使用しています。データベースから多数の異なるオブジェクトをロードしてローカルで変更するサーバー アプリケーションですが、コミットが発行されるたびにそれらの更新をデータベースに保存したくありません。私は以前、いくつかの Web プロジェクトで 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 分ごとに保存したいと考えています。

4

3 に答える 3

4

私は次のようなものを使用します:

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

これはあなたが達成しようとしていたものですか?

于 2012-11-27T06:27:40.933 に答える
2

私はあなたの苦境を理解しているかどうかわかりません.

ジャンゴでは、

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 への移行が容易になると思います。

アップデート

このような状況では、複数のセッションを使用できます。

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

テーブル users には 2 つのレコードが含まれます

1: foo, 10
2: bar, 20

session1 を使用して「foo」レコードを取得し、session2 を使用して「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() 
于 2012-07-25T11:14:24.510 に答える
0

古い記事を騒がせるわけではありませんが、

あなたは言う:

各オブジェクトの変更を 5 分ごとに保存したいと考えています。

それでは、Celery のようなスケジューラを使用してみませんか(私はpyramid_celeryを使用しています) 。

これにより、各オブジェクトを 5 分ごとに保存できます。つまり、デコレータを追加できます。

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

これは、特にデータベースを更新して最新の状態にする必要がある場合にうまく機能します (システムを使用しているユーザーが多い場合)。

これが、 5分ごとに節約できる誰かの助けになることを願っています。

于 2014-02-24T14:56:49.927 に答える