2017-01-28 12 views
0

我々はピーウィーデータベースが定義されているファイルdb.pyあります)( `アトミック使用せずにピーウィーとの取引を使用して`

db = PostgresqlExtDatabase('mom', 
          user=DB_CONFIG['username'], 
          password=DB_CONFIG['password'], 
          host=DB_CONFIG['host'], 
          port=DB_CONFIG['port'], 
          threadlocals=True, 
          register_hstore=False, 
          autocommit=True, 
          autorollback=True, 
          cursor_factory=DictCursor) 

予想通りdb.execute("SOME RAW SQL UPDATE QUERY")作品を呼び出します。 しかし、その前にbeginを呼び出しても、DBは変更されません。

db.begin() 
db.execute("SOME RAW SQL UPDATE QUERY") # <- Does not wait, db is updated immediately here 
db.commit() 

私はこれを正しく行いますか?

私は基本的にトランザクションが生存している場合は、トランザクション内に未処理のSQLをネストする必要があります。 トランザクションがない場合はすぐにそれを実行します。beginが呼び出されます。

これは、私がdb.set_autocommit(False)を実行した場合、execute_sqlを入力し、次にcommit()とすると、正常に動作します。
atomic()コンテキストマネージャ内でも動作します。


いくつかのコンテキストを与えるために、私は、物流上、Webアプリケーションに取り組んで と私たちのコードベースをTrueに設定autocommitでフラスコSQLAlchemyのscoped_sessionを使用しています。 これは(これは..歴史的な理由に)SQLAlchemyのORMを使用してだけでなくSessionオブジェクトとその ​​、begin()begin_nested()rollback()remove()方法を使用しません。

それは、ファイルに をセッションSession = scoped_session(sessionmaker(autocommit=True))を定義して、コードベースでどこでもsession = Session()を呼び出し、そして時にはsession.execute("SQL") を使用してクエリを実行することであるない方法、session.begin()が呼び出されるので、クエリがするまで実行されません。コミット(またはロールバック)。

私たちは今本当にpeeweeを使いたいと思います。 しかし、このセッションでコードベースが構築されています。だから、これは偽装されなければなりません。 すべてのファイルを移動して変更することは不可能であり、起動するテストケースが十分ではありません(歴史的な理由から)。


はまた、私はいくつかの質問があったが、私は彼らに聞いてどこかわからないので、私は、私はここにそれらを置く場合は、気にしないことを望む:

  • は、このDBオブジェクトです(とその接続)は、実行中のスレッドにバインドされていますか? dbが2つの異なるファイルからインポートされ、それぞれからdb.begin()が呼び出されると、基本的にいくつかのバグがありますか? 上記のdbオブジェクトのidがスレッドごとに同じであることをipythonシェルで確認することができます。 psycopg2接続が再作成されない限り、これは分離する必要があると仮定して正しいですか? SQLAlchemyのSessionを偽装する

  • 、私は必要なセッションの種類を返すラッパークラス、 SQLA Sessionオブジェクト、または私はそれを偽装するためにピーウィーのために書かれてきたラッパーを作成しました。

    class SessionMocker(object): 
        # DO NOT make this a singleton. Sessions will break 
    
        def __init__(self, orm_type=ORM_TYPES.SQLA): 
         assert orm_type in ORM_TYPES, "Invalid session constructor type" 
         super(SessionMocker, self).__init__() 
         self.orm_type = orm_type 
    
        def __call__(self, *args, **kwargs): 
         if self.orm_type == ORM_TYPES.SQLA: 
          return SQLASession(*args, **kwargs) 
    
         if self.orm_type == ORM_TYPES.PEEWEE: 
          # For now lets assume no slave 
          return SessionWrapper(*args, **kwargs) 
    
         raise NotImplementedError 
    
        def __getattr__(self, item): 
         """ 
         Assuming this will never be called without calling Session() first. 
         Else there is no way to tell what type of Session class (ORM) is required, since that can't be passed. 
         """ 
    
         if self.orm_type == ORM_TYPES.SQLA: 
          kls = SQLASession 
         elif self.orm_type == ORM_TYPES.PEEWEE: 
          kls = SessionWrapper 
         else: 
          raise NotImplementedError 
    
         return getattr(kls, item) 
    
    Session = SessionMocker(ORM_TYPES.SQLA) 
    

私は、これはコードベースはどこにでもそれを変更することなく、ピーウィーを使用する上で、透明かつシームレスな切り替えを行うことができます考え出しました。 これをよりうまくいくにはどうすればいいですか?

答えて

-1

自動コミットのデフォルト値はTrueですが、オートロールバックのデフォルト値はFalseです。 autorollbackをTrueに設定すると、クエリの実行中に例外が発生すると自動的にロールバックされます。確かではないかもしれないが、多分この状況を混乱させる。あなたはドキュメントがこれを行う方法を説明し偽

2

としてautorollbackでそれを試してみたいのであれば、:http://docs.peewee-orm.com/en/latest/peewee/transactions.html#autocommit-mode

しかし、TLを、DRは、あなたが自動コミットを無効にする必要がある前に開始/コミット/ロールバックがあなたのように動作します期待:

db.set_autocommit(False) 
db.begin() 
try: 
    user.delete_instance(recursive=True) 
except: 
    db.rollback() 
    raise 
else: 
    try: 
     db.commit() 
    except: 
     db.rollback() 
     raise 
finally: 
    db.set_autocommit(True) 
+0

私は、実際に私は内部で 'atomic'を呼び出す' SessionWrapper'オブジェクトの内部で、あなたの '_atomic'、' transaction'と 'savepoint'コンテキストマネージャをラップしようとしたことを試してみました、しかし、私はsqlalchemyのスコープセッションだけでコミットとロールバック以上のものだと思います。結局、ピューニーのための計画を落とさなければなりませんでしたが、将来私たちのマイクロサービスでそれを使用できることを願っています。それはまさに私たちが必要としているようです。 ラッパーを調べる場合は、私はあなたにそれを送ることができますか? – kunl

+0

それはあなたには役に立たない場合、私はそれを見てどのような利益があるか分からない。 SQLAlchemyの幸運、tho – coleifer

+0

とにかく、ありがとう、すばらしい図書館のおかげでありがとう。私は軽量プロジェクト用のより簡単なORMがほしいと思っていました。また、フィルタ( 'some__join')のようなdjangoのサポートを完全に落としていますか? – kunl

関連する問題