es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Psycopg2 copy_from csv ignorar comas en fila.

Estoy tratando de copiar un archivo csv en una tabla de postgres (phsyical) utilizando el método copy_from de psycopg2.

columnas = (
    'upc',
    'date',
    'type',
    'country_code',
    'customer'
    )

def insertar_csv(f, columnas):
    conexión = obtener_conexión_postgres()  
    cursor = conexión.cursor()
    cursor.copy_from(f, 'physical', sep=',', columns=columnas)
    conexión.commit()

Tengo un id generado automáticamente para cada fila que no estoy incluyendo en las columnas.

Sin embargo, algunas de las filas tienen comas dentro de las celdas. Al solucionar problemas, puedo ver las filas que tienen errores:

1111111,2021-02-28 00:00:00,,US,"Name, The"

Encontré esta pregunta de stackoverflow y probé:

cursor.copy_expert("COPY physical FROM STDIN WITH (FORMAT CSV)", f)

Pero esto causa un error con el que me estaba encontrando antes cuando no especificaba las columnas que quería.

value "1111111" is out of range for type integer
CONTEXT: COPY physical, line 1, column id: "1111111"

¿Alguien conoce una solución para esto?

Código de trabajo actualizado:


def insertar_csv(f, tabla, columnas):
conexión = obtener_conexión_postgres()
cursor = conexión.cursor()
try:
nombres_columnas = ','.join(columnas)
consulta = f'''
COPY {tabla}({nombres_columnas})
FROM STDOUT (FORMAT CSV)
'''
cursor.copy_expert(consulta, f)
conexión.commit()
return True
except (psycopg2.Error) as e:
print(e)
return False
finally:
cursor.close()
conexión.close()


columnas = (
"upc",
"date_thru",
"transaction_type",
"transaction_type_subtype",
"country_code",
"customer",
"quantity",
"income_gross",
"fm_serial",
"date_usage"
)


with open(archivo_dump, 'r', newline='', encoding="ISO-8859-1") as f:
insertado = insertar_csv(f, 'physical', columnas)

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema aquí es que el método copy_from espera un objeto similar a un archivo con un archivo separado por delimitadores, pero cuando hay comas dentro de una celda, puede causar errores. Una solución a esto es usar el método copy_expert en su lugar, que le permite escribir manualmente el comando COPY y ejecutarlo.

    Aquí está un fragmento de código actualizado que utiliza copy_expert:

    def insert_csv(f, table, columns):
        connection = get_postgres_connection()
        cursor = connection.cursor()
        try:
            column_names = ','.join(columns)
            query = f'''
                COPY {table}({column_names})
                FROM STDIN (FORMAT CSV)
                '''
            cursor.copy_expert(query, f)
            connection.commit()
            return True
        except (psycopg2.Error) as e:
            print(e)
            return False
        finally:
            cursor.close()
            connection.close()
    

    Con esta función actualizada, puede pasar el objeto similar a un archivo, el nombre de la tabla y la lista de columnas como parámetros, y escribirá manualmente el comando COPY utilizando los nombres de columna y lo ejecutará utilizando el método copy_expert.

    Asegúrese de incluir la opción FORMAT CSV en el comando COPY y de usar FROM STDIN, ya que está pasando un objeto similar a un archivo.

    ¡Espero que esto ayude! Hágamelo saber si tiene alguna pregunta.

Comments are closed.