Si solo está insertando una sola fila a la vez, puede crear un punto de guardado antes de la inserción y rollback cuando la inserción falla (o liberarlo cuando la inserción tiene éxito).
Para Postgres 9.5 o posterior, puede usar INSERT ... ON CONFLICT DO NOTHING
que hace lo que dice. Puedes también escribe ON CONFLICT DO UPDATE SET column = value...
, que convertirá automáticamente su inserción en una actualización de la fila con la que está en conflicto (esta funcionalidad a veces se denomina "upsert").
Esto no funciona porque OP está tratando con una clave externa restricción en lugar de un único restricción. En ese caso, puede usar más fácilmente el método de punto de guardado que describí anteriormente, pero para varias filas puede resultar tedioso. Si necesita insertar varias filas a la vez, debería tener un rendimiento razonable dividirlas en varias declaraciones de inserción, siempre que no estás trabajando en modo de confirmación automática , todas las inserciones ocurren en una transacción y no está insertando una gran cantidad de filas.
A veces, realmente necesita múltiples inserciones en una sola declaración, porque la sobrecarga de ida y vuelta de hablar con su base de datos más el costo de tener puntos de guardado en cada inserción es simplemente demasiado alta. En este caso, hay una serie de enfoques imperfectos. Probablemente el menos malo es crear una consulta anidada que seleccione sus datos y los una con la otra tabla, algo como esto:
INSERT INTO table_A (column_A, column_B, column_C)
SELECT A_rows.*
FROM VALUES (...) AS A_rows(column_A, column_B, column_C)
JOIN table_B ON A_rows.column_B = table_B.column_B;