MagicStack / MagicStack/asyncpg

set_type_codec encoder to handle numpy/pandas null types not working with copy_records_to_table

Aperta
#693 3 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Lingua principale
Python
Stelle
8.1k
Fork
468
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

* **asyncpg version**:0.21.0
* **PostgreSQL version**: PostgreSQL 13.1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), 64-bit
* **Do you use a PostgreSQL SaaS? If so, which? Can you reproduce
the issue with a local PostgreSQL install?**:
* **Python version**: 3.7
* **Platform**: Ubuntu 18.04
* **Do you use pgbouncer?**: no
* **Did you install asyncpg with pip?**: yes
* **If you built asyncpg locally, which version of Cython did you use?**: -
* **Can the issue be reproduced under both asyncio and
[uvloop](https://github.com/magicstack/uvloop)?**: -

I am trying to set up an asyncpg in order to use ```copy_records_to_table``` method passing pandas data frame, converted to list of lists.

My table is simple:
```sql
create table sg.test("no" int4, dt timestmap)
```

As pandas/numpy have their own Null types for different types (pd.NaT for dates and np.nan for numerics) I tried to set up an appropriate encoder:

```python
import asyncio
import asyncpg
import pandas as pd
import numpy as np

data = [[1, np.datetime64('NaT')]]
df = pd.DataFrame(data=data, columns=["no", "dt"])

def encoder(val):
if isinstance(val, (type(pd.NaT), type(np.nan))):
return None
return bytes(val)

def decoder(val): # we do not need that for this task
return val

async def main(df: pd.DataFrame):

conn: asyncpg.Connection=await asyncpg.connect('postgresql://connection_string')

try:
await conn.set_type_codec(
'timestamp',
encoder=encoder,
decoder=decoder,
schema='pg_catalog',
format='binary'
)
res=await conn.copy_records_to_table('test', records=df.values.tolist(), columns=df.columns.values.tolist(), schema_name='sg')
print(res)
except ValueError as e:
print(e.args)
finally:
await conn.close()

asyncio.get_event_loop().run_until_complete(main(df))
```
I am getting following error:
```log
....
File "asyncpg/protocol/protocol.pyx", line 482, in copy_in
File "asyncpg/protocol/protocol.pyx", line 429, in asyncpg.protocol.protocol.BaseProtocol.copy_in
File "asyncpg/protocol/codecs/base.pyx", line 192, in asyncpg.protocol.protocol.Codec.encode
File "asyncpg/protocol/codecs/base.pyx", line 178, in asyncpg.protocol.protocol.Codec.encode_in_python
File "asyncpg/pgproto/./codecs/bytea.pyx", line 19, in asyncpg.pgproto.pgproto.bytea_encode
TypeError: a bytes-like object is required, not 'NoneType'
```

For me it is unclear what kind of bytes should ```encoder``` return in case of Null value, I have tried to investigate it backwards: select a null value from original table with custom decoder, but it seems that ```asyncpg``` just amends that method in case of null values at all. So it is still unclear what kind of data should be passed.

I have already tried to return following values at ```encoder```:
- ```b''```
- ```b'\x01'```
another error occurs:
```log
insufficient data left in message
````

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia con le voci dello stack trace di copy_in e Codec.encode in asyncpg/protocol/protocol.pyx e asyncpg/protocol/codecs/base.pyx, quindi esamina asyncpg/pgproto/./codecs/bytea.pyx. Riproduci l’esempio di set_type_codec e copy_records_to_table con valori null di pandas e NumPy; il lavoro è completato quando il comportamento nullo previsto per questo percorso è stabilito e coperto.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
numpy, pandas, postgresql, python
Ambito
databases
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Da chiarire
Idoneità per principianti
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.