2016-07-01 16 views
0

ユーザファイルを保持するために使用されるpostgresテーブルがあります。 2人のユーザーが同じ名前のファイルを持つことはできますが、ユーザーは同じ名前のファイルを2つ持つことはできません。現在、ユーザーがすでに使用している名前のファイルをアップロードしようとすると、データベースは以下のようなエラーを吐き出します。私がやりたい何条件に基づいて行を挿入する

IntegrityError: duplicate key value violates unique constraint "file_user_id_title_key"

は、ファイル名がユーザーによって使用されているかどうかを確認するために、ファイル名とユーザーIDでデータベースを最初の照会です。名前がすでに使用されている場合はエラーを返し、そうでない場合は行を書き込みます。

cur.execute('INSERT INTO files(user_id, title, share)' 
      'VALUES (%s, %s, %s) RETURNING id;', 
      (user.id, file.title, file.share)) 
+3

しかし、これがユニーク制約がすることです。あなたはあなたのメッセージにエラーを入れました。あなたはトラップして、好きなように処理するだけです。 –

+0

私は、ユニークな制約があるにも関わらず、バックエンドがデータベースの前にエラーをキャッチすることを望んでいました。 – Brosef

+0

プライマリキーシーケンスをリセットする - シーケンスが壊れているhttp://stackoverflow.com/questions/244243/how-to-reset-postgres-primary-key-sequence-when-it-falls-out-of-sync – dmitryro

答えて

0

問題は、あなたが本当に競合状態を開かずにいることはできないということです。
あなたがテーブルを照会し、挿入しようとすると時間の間で競合する行を挿入するから、他の誰かを保つためには何もありませんあなたがそれを行う前にテーブルをロックするような極端な手段に向かわないと、並行処理に悪影響を及ぼします。

さらに、提案されている手法では、余分な2番目のクエリを追加することで、データベースに余分な負荷がかかります。

あなたは、データベース・エラー・メッセージをユーザに立ち向かうべきではないことを右ですが、次のようにこれを処理するための正しい方法は次のとおりです。

  • あなたはあなたのような新しい行があったINSERT
  • エラーが発生したかどうかを確認します。
  • エラーのSQLSTATEがSQL標準値23505(unique_violation)である場合、ユーザーにはそのようなファイルが既に存在し、ユーザーに適切なエラーが表示されていることがわかります。

だから、一致するエントリがすでに存在する場合アトミック操作としてチェックをINSERT文を検討し、そうでない場合、行を追加することができます。

関連する問題