Ao executar um arquivo \copy
(pgadmin ou aws_s3.table_import_from_s3
) de 1,6 GB em um banco de dados compatível com o AWS Aurora Postgres, recebo o seguinte erro:
ERROR: invalid byte sequence for encoding "UTF8": 0xdc 0x36
CONTEXT: COPY staging, line 99779: "L24000403170365 ACTIVEZONE LLC ..."
EDIT: Aqui está o que eu consegui extrair para a definição da tabela (mas me avise se quiser mais):
nome_da_coluna | tipo_de_dados | comprimento_máximo_de_caractere | é_anulável | coluna_padrão |
---|---|---|---|---|
cru | texto | [nulo] | SIM | [nulo] |
EDIT: Também tentei alterar a coluna, mas bytea
não obtive efeito.
A fonte deveria ser ASCII, mas recebo o mesmo erro com codificações explícitas como utf8
, latin1
, win1251
, e win1252
. EDIT: Conforme solicitado em uma resposta, aqui estão mais informações sobre os comandos de importação. No pgadmin4, estou importando com o botão direito do mouse na tabela que mostra o seguinte sob as capas:
--command " "\\copy public.staging (\"raw\") FROM 'C:/data.txt' DELIMITER '|' ENCODING 'UTF8';""
Eu também uso o pgadmin4 para acionar a importação da tabela s3 chamando a consulta:
SELECT aws_s3.table_import_from_s3(
'staging',
'',
'(DELIMITER ''|'')',
aws_commons.create_s3_uri('data', 'data.txt', 'us-east-1')
);
Debaixo das cobertas, table_import_from_s3
chama o comando:
copy staging from '/rdsdbdata/extensions/aws_s3/{{internal filename}}' with (DELIMITER '|')
A resposta para perguntas semelhantes é limpar os dados de origem, então eu abri o python e tentei encontrar o caractere ofensivo. Não consegui encontrar nenhuma evidência de um caractere incomum na linha referenciada ou ao redor dela. Para fins de argumentação, acredito que o seguinte escaneará o arquivo inteiro (e você pode ver os resultados em linha):
>>> def charinfile(filename, bytechar):
... with open(filename, 'rb') as file:
... byteline = file.readline()
... while byteline: # readline returns empty string at EOF
... if byteline.find(bytechar) != -1:
... print("found!")
... return byteline
... byteline = file.readline()
... else:
... print("not found")
...
>>> charinfile(filename, b'\xdc')
not found
>>> charinfile(filename, b'\xdc36')
not found
>>> charinfile(filename, b'6') # make sure the code is working
found!
Também tentei versões em que uso strings em vez de bytes com os mesmos resultados. Posso confirmar que não há linhas em branco antes do EOF (usei contadores de linha para verificar se cheguei a ~1m de linhas).
O que estou perdendo?