postgresql: cómo get las keys primarias de las filas insertadas con una copy masiva de copy_from?

El objective es este: tengo un set de valores para entrar en la tabla A y un set de valores para entrar en la tabla B Los valores entran en B valores de reference B en A (a través de una key externa), por lo que después de insert los valores A , necesito saber cómo hacer reference a ellos cuando inserte los valores B Necesito que esto sea lo más rápido posible.

Hice insert los valores B con una copy masiva de:

 def bulk_insert_copyfrom(cursor, table_name, field_names, values): if not values: return print "bulk copy from prepare..." str_vals = "\n".join("\t".join(adapt(val).getquoted() for val in cur_vals) for cur_vals in values) strf = StringIO(str_vals) print "bulk copy from execute..." cursor.copy_from(strf, table_name, columns=tuple(field_names)) 

Esto fue mucho más rápido que hacer una consulta de INSERT VALUES ... RETURNING id . Me gustaría hacer lo mismo con los valores A , pero necesito conocer los id de las filas insertadas.

¿Hay alguna manera de ejecutar una copy masiva de esta manera, pero para get el campo de id (key principal) de las filas que se insertan, de modo que sé qué id asocia con qué value ?

Si no, ¿cuál sería la mejor manera de lograr mi objective?

EDITAR: datos de muestra a petición:

 a_val1 = [1, 2, 3] a_val2 = [4, 5, 6] a_vals = [a_val1, a_val2] b_val1 = [a_val2, 5, 6, 7] b_val2 = [a_val1, 100, 200, 300] b_val3 = [a_val2, 9, 14, 6] b_vals = [b_val1, b_val2, b_val3] 

Quiero insert los a_vals , luego insert los b_vals , usando keys externas en lugar de references a los objects de la list.

Genere los ID usted mismo.

  1. BEGIN transacción
  2. Bloquear una table
  3. llame a nextval () – esa es su primera identificación
  4. genera tu COPIA con ID en su lugar
  5. lo mismo para la table b
  6. llame a setval () con su identificación final + 1
  7. Transacción COMPROMISO

En el paso 2 probablemente también quieras bloquear la relación de la secuencia. Si el código llama a nextval () y almacena ese ID en alguna parte, puede que ya esté en uso cuando lo use.

Hecho ligeramente fuera de tema: hay una configuration de "caching" que puede establecer si tiene muchos backends haciendo muchas inserciones. Eso incrementa el contador en bloques.

http://www.postgresql.org/docs/9.1/static/sql-createsequence.html

En realidad, puedes hacerlo de manera diferente, lo que necesitas es:

  • Comience la transacción
  • Crear tabla temporal con el mismo esquema (o casi el mismo)
  • COPY datos en esa tabla temporal
  • Realice regullar INSERT INTO .. FROM temp_table ... RETURNING id, other_columns
  • Cometer

tomado de aquí (en c #, pero algo es lo mismo)