zillow / ctds

Python DB-API 2.0 library for MS SQL Server
MIT License
83 stars 12 forks source link

Rounding issue for decimal. #90

Open xs005 opened 3 years ago

xs005 commented 3 years ago

I am trying to use ctds build_insert to insert a list of dictionaries to mssql. I found something unusual, for the column defined as numeric(8,2). The float 77.4930 will be rounded to 77.48, and 339.6490 will be rounded to 339.64.

I tried to round them with round(value, 2), and 339.6490 is rounded to 339.65 and is inserted to 339.65. 77.4930 is rounded to 77.49 but is still inserted to 77.48.

Any thought?

mssql version: 2017 ctds version: 1.14.0

joshuahlang commented 3 years ago

I'm not able to reproduce this issue using:

import pprint
import ctds

print('ctds version: ' + '.'.join(map(str, ctds.version_info)))
print('FreeTDS version: ' + ctds.freetds_version)

with ctds.connect(
    'localhost',
    user='SA',
    password='cTDS-unitest123'
    ) as connection:
    with connection.cursor() as cursor:
        cursor.execute('SELECT @@VERSION')
        print(cursor.fetchone()[0])

        cursor.execute(
            '''
            DROP TABLE IF EXISTS RoundingTest
            '''
        )
        cursor.execute(
            '''
            CREATE TABLE RoundingTest(
                NumericColumn NUMERIC(8,2),
                NumericColumn2 NUMERIC(12,5)
            )
            '''
        )

        connection.bulk_insert(
            'RoundingTest',
            [
                [77.4930] * 2,
                [339.6490] * 2,
            ]
        )

        cursor.execute(
            '''
            SELECT * FROM RoundingTest
            '''
        )

        pprint.pprint(
            list(map(tuple, cursor.fetchall()))
        )

I get the following output:

ctds version: 1.14.0
FreeTDS version: freetds v1.2.10
Microsoft SQL Server 2017 (RTM-CU24) (KB5001228) - 14.0.3391.2 (X64) 
    Apr 28 2021 10:32:18 
    Copyright (C) 2017 Microsoft Corporation
    Developer Edition (64-bit) on Linux (Ubuntu 16.04.7 LTS)
[(Decimal('77.49'), Decimal('77.49300')),
 (Decimal('339.65'), Decimal('339.64900'))]

What version of FreeTDS are you using?