Eu tenho essa função python definida localmente que funciona bem ao inserir dados em uma tabela redshift:
def _insert_data(table_name, values_list):
insert_base_sql = f"INSERT INTO {table_name} VALUES"
insert_sql = insert_base_sql + ','.join([str(row) for row in values_list])
<run_local_python_code_to_execute_insert_sql>
A values_list
é uma lista de tuplos, cada um com o mesmo número de elementos como colunas em table_name
(embora não explicitamente fazer valer / verificação de que nesta função). No entanto, não estou conseguindo encontrar uma maneira de inserir um NULL
valor para uma smallint
coluna. Este é o esquema para a tabela em questão (nenhum DEFAULT
valor foi atribuído às colunas na criação da tabela):
schemaname | tablename | column | type | encoding | distkey | sortkey | notnull
------------+---------------------+--------------+-----------------------+----------+---------+---------+---------
public | table | col1 | bigint | lzo | t | 1 | f
public | table | col2 | date | lzo | f | 2 | f
public | table | col3 | smallint | lzo | f | 3 | f
public | table | col4 | smallint | lzo | f | 4 | f
public | table | col5 | double precision | none | f | 0 | f
public | table | col6 | bigint | lzo | f | 0 | f
public | table | col7 | character varying(48) | bytedict | f | 0 | f
Estou especificamente tentando inserir NULL
valores para col3
e col4
; Eu tentei tuplas criando com ''
e 'NULL'
mas executar para esse erro: Error: invalid input syntax for integer: "NULL"
.
Para valer a pena, veja como uma linha limpa acaba ficando na INSERT
instrução:('bigint_value', 'dt_value', 'NULL', 'NULL', 'double_value', 'bigint_value', 'string_name')
A abordagem que você está adotando é bastante perigosa por si só. A construção de consultas usando concatenação e formatação de strings é propensa a erros e não é segura - você está tornando sua consulta vulnerável a ataques de injeção SQL .
Em vez disso, parametrize corretamente sua consulta, passando uma lista de parâmetros como um argumento separado para o cursor.executemany()
. Esta é uma maneira não muito bonita de gerar marcadores de posição:
placeholders = ", ".join(["%s"] * len(values_list))
query = f"""
INSERT INTO
{table_name}
VALUES
({placeholders})
"""
cursor.executemany(query, values_list)
(observe que o nome da tabela não pode ser parametrizado - higienize e valide-o separadamente)
Observe o uso de executemany()
- ele executaria uma instrução de consulta preparada para cada tupla no values_list
.
Mas, se você estiver usando psycopg2
, há uma maneira ainda melhor de inserir vários registros na tabela execute_values()
- dê uma olhada nesta resposta .
E, voltando à sua pergunta inicial - se você seguir essa abordagem, os None
valores de espaço reservado seriam automaticamente convertidos em 'NULL'
strings pelo driver do banco de dados .
Este artigo é coletado da Internet.
Se houver alguma infração, entre em [email protected] Delete.
deixe-me dizer algumas palavras