Closed mdobrzanski closed 2 years ago
I am curious because I cannot recreate this symptom with environment Using this mix:
ibm_db_sa 0.3.5
sqlalchemy 1.3.16
chinook db 1.4 ddl from github
Db2 v11.1.4.4a with local databases
unixODBC 2.3.1-4.1
ubuntu 16.04.06.
python 3.6.8 in virtualenv
and my sample fragment of code is below. There is no exception thrown, not sure why I don't see your symptom.
import urllib
from sqlalchemy import create_engine
from sqlalchemy.ext.automap import automap_base
# authenticating via kerberos, all details in ~/.odbc.ini and db2dsdriver.cfg
CONNECTION_STRING=("DSN=CHINOOK;")
engine = create_engine('db2+pyodbc:///?odbc_connect={}'.format(CONNECTION_STRING))
engine.connect()
Base = automap_base()
Base.prepare(engine, reflect=True)
That is interesting, below s a better description of the environment. Still fails.
What is the UnixODBC version that you used?
DB2 v11.5 on docker
docker pull ibmcom/db2
docker run -itd --name mydb2 --privileged=true -p 50000:50000 -e LICENSE=accept -e DB2INST1_PASSWORD=p4ssw0rd -e DBNAME=testdb -e SAMPLEDB=true ibmcom/db2
Python 3.6.8 with
pyodbc==4.0.30
ibm-db==3.0.1
ibm-db-sa==0.3.5
SQLAlchemy==1.3.16
UnixODBC 2.3.7 /etc/odbcinst.ini
[DB2]
Driver = /home/mike/envs/mypy3/lib/python3.6/site-packages/clidriver/lib/libdb2.so
FileUsage = 1
DontDLClose = 1
Linux uname -a
Linux pure-power 4.15.0-99-generic #100-Ubuntu SMP Wed Apr 22 20:32:56 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
Python script
from sqlalchemy import create_engine
from sqlalchemy.ext.automap import automap_base
connstr = 'db2+pyodbc://db2inst1:p4ssw0rd@127.0.0.1:50000/SAMPLE?driver=DB2'
engine = create_engine(connstr)
Base = automap_base()
Base.prepare(engine, reflect=True)
and the same error
sqlalchemy.exc.ProgrammingError: (pyodbc.ProgrammingError) ('ODBC SQL type -99 is not yet supported. column-index=2 type=-99', 'HY106')
(Background on this error at: http://sqlalche.me/e/f405)
OK found that my database had oracle-compatibility ENABLED. This allows it to work. By this i mean that the Db2-instance had registry setting DB2_COMPATIBILITY_VECTOR=ORA defined and effective before creating the chinook database.
When I connect to a database that has oracle-compatibility DISABLED (which is the default), then I can recreate your symptom exactly.
Hi @mdobrzanski
Can this issue be closed, or do you still have more queries related to this.
Thanks
@amukherjee28 that is a way to patch it, but shouldn't reflect work even if oracle compatibility is disabled?
@mdobrzanski This is a database setting you are talking about and I would like not to patch it in the existing adapter code. This is something best left untouched from the adaptor code and can be controlled from the database end whenever needed.
The Db2 setting vary from user to user based on everyone requirement and hence modifying these would be in the best of interest.
@amukherjee28 it looks like some changes fd86d6a have been made. From the code it looks like the default is set to None for pyodbc. I wanted to verify how it works now. I pulled the latest from master branch and tried the example again but I'm getting error regarding creating connection
File "/home/mike/envs/sandbox/lib/python3.6/site-packages/ibm_db_sa/base.py", line 725, in initialize
elif "DB2/" in self.dbms_name:
TypeError: argument of type 'NoneType' is not iterable
Is there something wrong with the connection string db2+pyodbc://db2inst1:p4ssw0rd@127.0.0.1:50000/SAMPLE?driver=SandboxDB2
?
@mdobrzanski Thanks for pointing this out.
The code change got removed because of the PR merge via commit https://github.com/ibmdb/python-ibmdbsa/commit/1e797163baab7c024df9d34e932b0da76ddb3832
I have restored the code and now this should work fine.
Thanks
@amukherjee28 error is gone. Run the script using ibm-db-sa latest code from master branch.
/etc/odbcinst.ini
[SandboxDB2]
Driver = /home/mike/envs/sandbox/lib/python3.6/site-packages/clidriver/lib/libdb2.so
FileUsage = 1
DontDLClose = 1
docker with db2 with sample database
docker run -itd --name mydb2 --privileged=true -p 50000:50000 -e LICENSE=accept -e DB2INST1_PASSWORD=p4ssw0rd -e DBNAME=testdb -e SAMPLEDB=true ibmcom/db2
for switching on/off oracle compatibility in db2 in docker container
su db2inst1
db2set DB2_COMPATIBILITY_VECTOR=ORA
db2set DB2_COMPATIBILITY_VECTOR=
db2stop
db2start
sandbox.py
from sqlalchemy import create_engine
from sqlalchemy.ext.automap import automap_base
# connstr = 'db2://db2inst1:p4ssw0rd@127.0.0.1:50000/SAMPLE'
connstr = 'db2+pyodbc://db2inst1:p4ssw0rd@127.0.0.1:50000/SAMPLE?driver=SandboxDB2'
engine = create_engine(connstr)
Base = automap_base()
Base.prepare(engine, reflect=True)
print(list(Base.classes))
I'm getting error
when making a reflection of Chinook database on DB2 10.5 server due column DEFAULT being of type CLOB and pyodbc does not support it. Is that default value necessary, since it's server side default?
My current walk around is by selecting
None
for default values when collecting column information https://github.com/ibmdb/python-ibmdbsa/blob/master/ibm_db_sa/ibm_db_sa/reflection.py#L240. Any drawbacks doing such?Below more detail:
Full traceback
The error is raised when executing sql for column information of tables in this reflection code https://github.com/ibmdb/python-ibmdbsa/blob/master/ibm_db_sa/ibm_db_sa/reflection.py#L240
The executed sql is like
According to below the column
"SYSCAT"."COLUMNS"."DEFAULT"
is CLOB.Pyodbc does not support CLOB or BLOB and there we get an error.