Skip to content

Connection.copy_records_to_table() fails on NUMERIC type #157

Closed
@sergeyspatar

Description

@sergeyspatar
  • asyncpg version: 0.11.0
  • PostgreSQL version: 9.6.3
  • Python version: 3.5.3
  • Platform: Linux x86_64 (Debian)
  • Do you use pgbouncer?: no
  • Did you install asyncpg with pip?: no
  • If you built asyncpg locally, which version of Cython did you use?: 0.25.2
  • Can the issue be reproduced under both asyncio and
    uvloop?
    : yes

It seems that NUMERIC values are not packed correctly for PGCOPY binary stream. I tried passing int, float and Decimal values and got the same error insufficient data left in message. Here is my example:

import asyncpg
import asyncio

#import uvloop
#asyncio.set_event_loop(uvloop.new_event_loop())

from decimal import Decimal

async def run():
    conn = await asyncpg.connect(user='postgres')
    await conn.execute('create temporary table temp_table (c1 numeric)')
    #await conn.copy_records_to_table('temp_table', records=[(123,)])
    #await conn.copy_records_to_table('temp_table', records=[(0.123,)])
    await conn.copy_records_to_table('temp_table', records=[(Decimal('0.123'),)])

asyncio.get_event_loop().run_until_complete(run())

Here is the traceback:

# python3 test_pgcopy_numeric.py
Traceback (most recent call last):
  File "test_pgcopy_numeric.py", line 16, in <module>
    asyncio.get_event_loop().run_until_complete(run())
  File "/usr/lib/python3.5/asyncio/base_events.py", line 466, in run_until_complete
    return future.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result
    raise self._exception
  File "/usr/lib/python3.5/asyncio/tasks.py", line 241, in _step
    result = coro.throw(exc)
  File "test_pgcopy_numeric.py", line 14, in run
    await conn.copy_records_to_table('temp_table', records=[(Decimal('0.123'),)])
  File "/usr/lib/python3/dist-packages/asyncpg/connection.py", line 619, in copy_records_to_table
    copy_stmt, records, intro_ps._state, timeout)
  File "/usr/lib/python3/dist-packages/asyncpg/connection.py", line 741, in _copy_in_records
    copy_stmt, None, None, records, intro_stmt, timeout)
  File "asyncpg/protocol/protocol.pyx", line 445, in copy_in (asyncpg/protocol/protocol.c:66303)
  File "/usr/lib/python3.5/asyncio/futures.py", line 380, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.5/asyncio/tasks.py", line 304, in _wakeup
    future.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result
    raise self._exception
asyncpg.exceptions.ProtocolViolationError: insufficient data left in message

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions