I am testing pyodbc, and wrote an extremely simple script. The database table has some numeric data types, and a datetime field. If I open an interactive python window, and import pyodbc, the following fails:
>>> import pyodbc
>>> print(Decimal('0.3'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'Decimal' is not defined
>>>
Clearly, pyodbc does not implicitly import decimal.
However, the script collects Decimal fields from the database, and prints them correctly. At no time did I import decimal, nor did I import datetime. What is happening? Can I rely on this?
The full script:
#! /usr/bin/env python
"""Tests odbc connections
"""
import pyodbc
def getData():
#returns a row set from the ODBC_Test database
conn_str="DSN=ODBC_Test"
cnx=pyodbc.connect(conn_str)
crsr=cnx.cursor()
sql="select id_num,entry_date,amt1,amt2,amt3,note from tbl3"
crsr.execute(sql)
columns = [column[0] for column in crsr.description]
print(columns) #a list of column names
rows=crsr.fetchall() #a list of tuples
results={}
n=0
for row in rows:
n+=1
key=row[0]
print('{} key:{}'.format(n,key))
results[key]=dict(zip(columns,row))
crsr.close()
cnx.close()
return results
data=getData()
print('data: {}'.format(data))
for k in data.keys():
for field in data[k].keys():
print("'{}': {}".format(field,data[k][field]))
all_modules=dir()
print(all_modules)
The output:
['id_num', 'entry_date', 'amt1', 'amt2', 'amt3', 'note']
1 key:1512075160
2 key:1512075027
data: {'1512075160': {'id_num': '1512075160', 'entry_date': datetime.datetime(2022, 3, 13, 11, 22), 'amt1': Decimal('0.18'), 'amt2': Decimal('0.35'), 'amt3': Decimal('0.02'), 'note': '$0.05 NL (6 max)'}, '1512075027': {'id_num': '1512075027', 'entry_date': datetime.datetime(2022, 3, 13, 11, 21), 'amt1': Decimal('0.00'), 'amt2': Decimal('1.17'), 'amt3': Decimal('0.06'), 'note': '$0.05 NL (6 max)'}}
'id_num': 1512075160
'entry_date': 2022-03-13 11:22:00
'amt1': 0.18
'amt2': 0.35
'amt3': 0.02
'note': $0.05 NL (6 max)
'id_num': 1512075027
'entry_date': 2022-03-13 11:21:00
'amt1': 0.00
'amt2': 1.17
'amt3': 0.06
'note': $0.05 NL (6 max)
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'data', 'field', 'getData', 'k', 'pyodbc']
table create script:
CREATE TABLE IF NOT EXISTS public.tbl3
(
id_row bigint NOT NULL,
id_num character varying(32) COLLATE pg_catalog."default" NOT NULL,
entry_date timestamp without time zone NOT NULL,
amt1 numeric(14,2) DEFAULT 0,
amt2 numeric(14,2) DEFAULT 0,
amt3 numeric(14,2) DEFAULT 0,
note character varying(32) COLLATE pg_catalog."default",
CONSTRAINT tbl3_pkey PRIMARY KEY (id_row)
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
Note: I looked at What is the best way of listing all imported modules in python? the output of the instructions in that question showed definitely that decimal had not been imported.
I'm using
- Python 3.9.5
- Windows 10
- postgresql 10