1

私はこのような挿入ステートメントを持っています:

insert = MyTable.insert()
row = {"foo": 42}
result = cxn.execute(insert, row)

ただし、Postgresトリガーは挿入を新しいテーブルにリダイレクトしmytableているため、insertステートメントは実際には何も返しません。

# INSERT INTO mytable VALUES (DEFAULT, 'stuff') RETURNING LASTVAL();
 lastval 
---------
(0 rows)

これにより、SQLAlchemy(0.8b2)は。を発生させTypeError: 'NoneType' is not subscriptableます。これはDefaultExecutionContext、挿入された行の主キーをフェッチしようとしたときに発生しているようです。

これは報告すべきバグですか?そして、SQLAlchemyに戻り値を期待しないように指示して、これを回避する方法はありますか?

トレースバック

… snip… 
  File "myfile.py", line 85, in store
    result = cxn.execute(insert, row)
  File ".../sqlalchemy/engine/base.py", line 664, in execute
    params)
  File ".../sqlalchemy/engine/base.py", line 764, in _execute_clauseelement
    compiled_sql, distilled_params
  File ".../sqlalchemy/engine/base.py", line 899, in _execute_context
    context._fetch_implicit_returning(result)
  File ".../sqlalchemy/engine/default.py", line 697, in _fetch_implicit_returning
    ipk.append(row[c])
TypeError: 'NoneType' object is not subscriptable

Postgresトリガー

CREATE OR REPLACE FUNCTION mytable_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO mytable_cur VALUES (NEW.*);
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER mytable_insert_trigger
    BEFORE INSERT ON mytable
    FOR EACH ROW EXECUTE PROCEDURE mytable_insert_trigger();
4

2 に答える 2

2

あなたはここで契約を破りました。Postgres バックエンドに対して、SQLAlchemy はINSERT ... RETURNING生成されたシーケンスから値などを取得できるように使用する傾向があります。行を挿入していますが、それについて嘘をついています。

ドキュメントに基づいて、INSTEAD OFトリガーではなくトリガーを使用し、行を変更せずBEFOREに返すようにしたいと思います。NEWPostgres は、必要な挿入が行われたと想定し、返された行をクライアントに戻すだけです。

于 2013-01-15T05:21:24.950 に答える
1

ええ、テーブルに対して行うことができるimplicit_returningをオフにすることで、最後に挿入されたIDを取得する古いシステムにフォールバックできます。

Table('sometable', metadata, ... columns ..., implicit_returning=False)

これがまっすぐなSERIAL主キーであると仮定すると、事前に「tablename_id_seq」を明示的に実行し、その値をINSERTステートメントで使用するだけです。

于 2013-01-15T16:15:34.723 に答える