sql >> データベース >  >> RDS >> PostgreSQL

カスタムPostgresqlエラーを発生させてEctoで処理する方法

    私の知る限り、カスタムPostgreSQLのエラーを処理するための組み込みのメカニズムはありません。ただし、リポジトリレベルで実行できます。

    これを行うには、ERRCODEを使用してPostgreSQLでエラーを発生させる必要があります のように:

    RAISE '[message for logs]' USING ERRCODE = 'integrity_constraint_violation';
    

    次に、アプリケーションでそれらを処理します:

    defmodule Core.Repo do
      use Ecto.Repo, otp_app: :core
    
      defoverridable insert: 2
    
      def insert(changeset, opts) do
        super(changeset, opts)
      rescue
        exception in Postgrex.Error ->
          handle_postgrex_exception(exception, __STACKTRACE__, changeset)
      end
    
      # ... other functions
    
      defp handle_postgrex_exception(exception, stacktrace, changeset \\ nil)
    
      defp handle_postgrex_exception(%{postgres: %{code: :integrity_constraint_violation}}, _, nil) do
        {:error, :integrity_constraint_violation}
      end
    
      defp handle_postgrex_exception(
             %{postgres: %{code: :integrity_constraint_violation}},
             _,
             changeset
           ) do
        {:error, %{changeset | valid?: false}}
      end
    
      defp handle_postgrex_exception(exception, stacktrace, _) do
        reraise(exception, stacktrace)
      end
    end
    

    {:error, %{changeset | valid?: false}} 応答。つまり、その時点では、表示する有用なメッセージはありません。

    PSおそらく、いくつかのマクロを記述してEctoの関数をオーバーライドし、そこで実装を非表示にすることができます(提案されたソリューションの代わりに)が、維持するのははるかに難しいと思います。



    1. postgres-where in(list)-列は存在しません

    2. mysql:whoami?

    3. SQLServerおよびMySQLで実行可能なテーブルの最大数

    4. MySQLはcounterのような複数のユーザーによって同じ行を更新します