2011-11-15 9 views
1

SQLAlchemyでPostgreSQLを使用していますが、サブクエリを使用するときにsqlalchemyで行を追加できないようです。sqlalchemyでサブクエリを使用して行を追加する方法は?

私の例では、テーブル内の特定のタグのカウンタを更新したいと考えています。 SQLAlchemyので

テスト実行クラスには、次のようになります。

class TestRun(base): 
    __tablename__ = 'test_runs' 

    id    = sqlalchemy.Column('id', sqlalchemy.Integer, sqlalchemy.Sequence('user_id_seq'), primary_key=True) 
    tag    = sqlalchemy.Column('tag', sqlalchemy.String) 
    counter   = sqlalchemy.Column('counter', sqlalchemy.Integer) 

挿入コードは、次のようになります。

tag = 'sampletag' 
counterquery = session.query(sqlalchemy.func.coalesce(sqlalchemy.func.max(TestRun.counter),0) + 1).\ 
          filter(TestRun.tag == tag).\ 
          subquery() 

testrun = TestRun() 
testrun.tag = tag 
testrun.counter = counterquery 

session.add(testrun) 
session.commit() 

これに伴う問題、それは非常に与えていますこのコードを実行しているときに面白いエラーが発生した場合、次のSQLクエリを実行しようとしています。

'INSERT INTO test_runs (id, tag, counter) 
    VALUES (%(id)s, 
      %(tag)s, 
      SELECT coalesce(max(test_runs.counter), %(param_1)s) + %(coalesce_1)s AS anon_1 
       FROM test_runs 
       WHERE test_runs.tag = %(tag_1)s)' 
{'coalesce_1': 1, 'param_1': 0, 'tag_1': 'mytag', 'tag': 'mytag', 'id': 267L} 

SELECT呼び出しの周りに括弧がないことを除いて、妥当に見えます。 SQLクエリを手動で実行すると、すべての問題を手動で修正する括弧を手動で入力するまで、sqlalchemyが私に与える正確なエラーが表示されます。 sqlalchemyが必要なときにかっこを入れることを忘れてしまうような疑わしいバグのように思えるので、sqlalchemyを使用して行を追加するときにサブクエリを正しく使用する関数が不足していますか?代わりにsubquery()コールas_scalar() method使用の

答えて

7

戻り、このクエリによって表される完全なSELECT文は、スカラー副問合せに を変換します。

例:クラス分け親子関係を持つ

モデル:更新する

class Parent(Base): 
    __tablename__ = 'parents' 
    id = Column(Integer, primary_key=True) 
    counter = Column(Integer, nullable=False, default=0) 

class Child(Base): 
    __tablename__ = 'children' 
    id = Column(Integer, primary_key=True) 
    parent_id = Column(ForeignKey(Parent.id), nullable=False) 
    parent = relationship(Parent) 

コードcounterフィールド:

SQL(ログからコピー)プロデュース
parent.counter = session.query(func.count(Child.id))\ 
        .filter_by(parent=parent).as_scalar() 

+0

これは重要なことではありませんが、問題は、sqlalchemyに正しいsqlコマンドを出力させる方法でした。 as_scalar()を使用すると、2つのSQLクエリに分離されます。これにより、複数のユーザーが同時に値を増やすことができるため、安全ではありません。 –

+0

@DavidYen、私が参照したドキュメントを読んだり、少なくとも読んだことがありますか?あなたが間違っていることを示す例を追加しました。おそらく、副問い合わせではなく結果を返す 'scalar()'メソッドと混同しているでしょう。 –

+0

申し訳ありませんが、あなたは正しいです。私はスカラー()としてそれを誤解しました。ありがとう! –

関連する問題