Pyodbc can't find FreeTDS driver - python

I am on a Centos 7 Linux machine trying to connect to an SQL database through pyodbc. I learned that you need to setup the DSN and you do that by installing the freetds driver and doing something like:
import pyodbc
cnxn = pyodbc.connect('DRIVER={FreeTDS};SERVER=example;DATABASE=TEST;')
Unfortunately when I do that I get an error saying the driver FreeTDS can't be found. I have ran:
$ ./configure
$ make
$ make install
It seemed to have installed it but I get the same error. Can someone please send me a link to a working example

If you're compiling FreeTDS from source, it'll install to /usr/local/freetds, IIRC. You can also install via yum on CentOS, and you'll need unixODBC as well. Basically, FreeTDS bridges SQL Server to unixODBC, and pyodbc bridges unixODBC to Python.
Here's an example set up with FreeTDS, unixODBC, and friends:
freetds.conf:
[server]
host = server.com
port = 1433
tds version = 7.3
odbc.ini:
[server]
Driver = FreeTDS
Server = server.com
Port = 1433
TDS_Version = 7.3
odbcinst.ini:
[FreeTDS]
Description = FreeTDS with Protocol up to 7.3
Driver = /usr/lib64/libtdsodbc.so.0
The Driver = location may differ above, depending on your distro of FreeTDS - if you compiled from source, most likely, /usr/local/freetds/lib/libtdsodbc.so.
pyodbc connect, DSN free:
DRIVER={FreeTDS};SERVER=server.com;PORT=1433;DATABASE=dbname;UID=dbuser;PWD=dbpassword;TDS_Version=7.3;
A few notes:
You'll have to update the TDS version to match the version of SQL Server you are running and the Free TDS version you are running. Version 0.95 supports TDS Version 7.3.
TDS Version 7.3 will work with MS SQL Server 2008 and above.
Use TDS Version 7.2 for MS SQL Server 2005.
See here for more:
https://msdn.microsoft.com/en-us/library/dd339982.aspx
Good luck.

To build on #FlipperPA's answer, it's not obvious how pyodbc "finds" the FreeTDS driver. If you have this error:
pyodbc.Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib 'FreeTDS' : file not found (0) (SQLDriverConnect)")
There can be other possible causes, including an incorrect environment. Here's what I discovered:
pyodbc is a wrapper around unixODBC, which isn't documented, but you need to install the unixODBC devel packages before you can pip install pyodbc. pyodbc passes the connection string directly to unixODBC.
unixODBC needs to load a shared library containing the ODBC database driver, for example libtdsodbc.so for FreeTDS. You can set the DRIVER parameter in the connect string to one of two things:
Either the direct path to the shared library file (e.g. /usr/local/lib/libtdsodbc.so)
Or the name of a config section in odbcinst.ini, which contains a Driver = ... setting that points to the shared library file
The first way is guaranteed to find the shared library, and a good way to check whether you have environment issues, but the second way is preferred and more portable. See here for more details:
This ini file simply lists all installed drivers. It is located in
/etc/odbcinst.ini. The syntax is simple; a name followed by a property
which tells us the drivers file name. For example;
[Sybase 11]
Comment = Super Duper Sybase Server
Driver = /usr/lib/libsybase.so.11
Setup = /usr/lib/libsybaseS.so.11
FileUsage = 1
The Driver file name (ie /usr/lib/libsybase.so.11) should be unique.
The friendly name (ie Sybase 11) must also be unique.
However, this can only work if unixODBC can find your odbcinst.ini file. It appears to search for it:
in your home directory with a modified name, .odbcinst.ini
In the directory pointed to by the ODBCSYSINI environment variable, if set.
Otherwise, in /etc.
For FreeTDS it should contain something like this:
[FreeTDS]
Description = For example, my database server name or FreeTDS version
Driver = /usr/local/lib/libtdsodbc.so
Only then can you use DRIVER=FreeTDS in a connect string and expect it to work (and not get the above error).
You might also want to use the ldd command (on Linux) to check that all of the library's dependencies are satisfied, and can be found and loaded by the dynamic library loader, ld.so:
ldd /usr/local/lib/libtdsodbc.so
ldd: warning: you do not have execution permission for `/usr/local/lib/libtdsodbc.so'
linux-vdso.so.1 => (0x00007ffe145fe000)
libodbcinst.so.2 => /lib64/libodbcinst.so.2 (0x00007f81f9dfd000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f81f9bf8000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f81f99dc000)
libc.so.6 => /lib64/libc.so.6 (0x00007f81f961b000)
libltdl.so.7 => /usr/local/lib/libltdl.so.7 (0x00007f81f940f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f81fa2ac000)
If you are still stuck, you might want to start over from scratch by following this or this answer.

Related

Python connect to ODBC 2.x database

I'm trying to connect to an old database that has its own equally old ODBC driver (which is no longer maintained)
# The driver is 32 bit, so I'm using Python 3.8.7 (32bit)
con = pyodbc.connect(r"Driver={CSI RBM 4.02 ODBC Driver};Dbq=" + database_path + ";Server=localhost")
But I'm getting this error:
[08001] [Microsoft][ODBC Driver Manager] The driver doesn't support the version of ODBC behavior that the application requested (see SQLSetEnvAttr).
According to https://knowledgebase.progress.com/articles/Article/000033360 it means:
This error indicates that an application requested ODBC 3.x behavior however the driver was only ODBC 2.x compliant.
Which I assume means that Python or Pyodbc is using ODBC 3.x and the driver is using 2.x.
So if I've assumed all that correctly, then my question is how can I force Pyodbc to use ODBC 2.x, or is there any other way I can connect to this database using Python?
Any other helpful information would be appreciated too
You can build it from source.
In the /src/pyodbcmodule.cpp file about at the 330 line change SQL_OV_ODBC3 to SQL_OV_ODBC2 then build and install.
I also have and ancient odbc driver what only works with SQL_OV_ODBC2 but hangs every time with SQL_OV_ODBC3.
/src/pyodbcmodule.cpp ~line 330
if (!SQL_SUCCEEDED(SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC2, sizeof(int) ) ) )
{
PyErr_SetString(PyExc_RuntimeError, "Unable to set SQL_ATTR_ODBC_VERSION attribute.");
return false;
}
You can find the source code and documentation for building from sourc here:
https://github.com/mkleehammer/pyodbc/wiki/Building-pyodbc-from-source
python setup.py build
python setup.py install
For driver testing you can use the ODBC Test tool from Microsoft.
You can try out any settings of the ODBC driver without writing any code.
https://learn.microsoft.com/en-us/sql/odbc/odbc-test?view=sql-server-ver15
https://www.microsoft.com/en-us/download/details.aspx?id=21995

Connecting to DB2 with pyodbc on Linux

I am trying to connect DB2 with pyodbc on linux and I get the error
"('01000', "[01000] [unixODBC][Driver Manager]Can't open lib 'IBM DB2 ODBC Driver' : file not found (0) (SQLDriverConnect)")## Heading ##
Is there some installation required or am I missing path?
# Create a connection object
cnxn = pyodbc.connect(
'Driver={IBM DB2 ODBC Driver}; '
'Hostname=nn.nn.nnn.nnn; '
'Port=50000; '
'Protocol=TCPIP; '
'Database=myDB; '
'CurrentSchema=myschema; '
'UID=user1; '
'PWD =test1;'
)
I tried to configure by following the link at https://www.ibm.com/support/knowledgecenter/en/SSEPGG_10.5.0/com.ibm.db2.luw.apdv.cli.doc/doc/t0061216.html
I did a
yum install unixODBC
But I could not find the path where libdb2.so was installed for configuring
odbcinst.int as given here
https://www.ibm.com/support/knowledgecenter/en/SSEPGG_10.5.0/com.ibm.db2.luw.apdv.cli.doc/doc/t0061216.html
What is the path for libdb2.so?
The driver-manager (unixODBC) does not supply a driver for the Db2 rdbms. Normally you will use a Db2-driver supplied by IBM which works with unixODBC.
If your Db2-server is remote from Linux then you need to install Db2 driver separately and configure it.
If your Db2-server is already installed locally on Linux, then it includes a local Db2-client already, and libraries are symlinked from the Db2-instance home directory sqllib/lib64 directory ( for example /home/db2inst1/sqllib/lib64 will contain the symlinks to the relevant libraries, if your Db2-instance is called "db2inst1"). In this case you don't need to install anything else.
Otherwise, there are various IBM supplied Db2-clients, so you have to choose the right one, which depends both on your Db2-server platform and your programming needs (different footprints for different drivers). There are also third party drivers, not mentioned here. See here for Db2 client types:
https://www.ibm.com/support/knowledgecenter/en/SSEPGG_9.5.0/com.ibm.swg.im.dbclient.install.doc/doc/c0022612.html
[ 1 ] If your remote Db2-server runs on Linux/Unix/Windows/zLinux then download your IBM driver from Passport Advantage (choose the latest driver version for your Db2-server version). Your Db2 DBA (if you have one) should also have an installable copy although it's always wise to download the latest version from Passport Advantage website as long as you have that access.
If your Db2-server runs on Z/OS or i-Series AND your company already has a Db2-connect gateway server installed and configured then you can use the same driver as [1] above. The Db2-connect gateway is a separate hostname that does the protocol conversion (if necessary) and allows easier licensing at a price.
If your remote Db2-server runs on i-Series (formerly OS/400) and your company is not using a Db2-connect gateway, ask your i Admin for the correct driver and install that on Linux. For i-Series you can either use a driver from IBM or from a third party, as long as it supports ODBC/CLI on Linux for your version and bitness.
If your Db2-server runs on Z/OS and your company does not use a Db2-connect gateway (i.e. instead you are connecting directly from Linux to Db2-for-Z/OS) then you will need to use the same driver as in [1] but additionally apply a suitable license file to your Linux Db2 driver. Your admin should know the details.

Pyodbc - The specified DSN contains an architecture mismatch between the Driver and Application

I'm trying to connect to a MS Access Database (.accdb file) via python.
I used pyodbc to do this connection:
import pyodbc
conn = pyodbc.connect("DRIVER = {Microsoft Access Driver (*.mdb, *.accdb)}; DBG=C:\\test_db.accdb")
However, I got the following error:
('IM002, '[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)')
I went to the ODBC Data Source Administrator and when I tried to configure or remove the Driver I got the message:
Errors Found:
The specified DSN contains an architecture mismatch between the Driver and Application
I found that this error is provoked by an incompatibility between versions of Windows (windows 7 - 64bit) and Microsoft Access (Office 2010 - 32bits).
I tried to reinstall the driver several times, both with 32 and 64bit versions but the problem wasn't solved.
Could you please help me to solve this problem? Thank you in advance.
You have to make sure the Python version matches the ODBC driver version: 32-bit with 32-bit, 64-bit with 64-bit.
It looks like you have 64-bit Python / pyodbc and 32-bit MS Access.
What you'll need to do is install the 32-bit Python version, and then install pyodbc.
Good luck!

Can Pymssql have a secure connection (SSL) to MS SQL Server?

I'm making queries from a MS SQL server using Python code (Pymssql library) however I was wondering if there was any way to make the connection secure and encrypt the data being sent from the server to python?
Thanks
Yes, it can.
You need FreeTDS which supports SSL via OpenSSL. If you happened to use Linux (or Docker on Windows), it's quite easy to install standalone FreeTDS in Debian:
apt-get update
apt-get install freetds-bin freetds-dev
pip install pymssql
Don't use pymssql with bundled FreeTDS library, it does not support SSL apparently. The bundled library is used when you set env variable PYMSSQL_BUILD_WITH_BUNDLED_FREETDS=1 before installing pymssql.
pymssql certainly claims to be able to work with encrypted connections to the SQL Server (via OpenSSL). One reason why some might believe it to be impossible is that Windows releases of pymssql versions prior to 2.1.2 were shipped with pymssql statically linked to FreeTDS for unencrypted connections only.
Starting with version 2.1.2, the Windows release of pymssql is shipped dynamically linked to FreeTDS so it can support both unencrypted connections (via FreeTDS alone) or encrypted connections (via FreeTDS and OpenSSL). For details – and an important update re: versions 2.1.3 and later – see the related answer here.
If you want to connect SQL server using secured connection using pymssql then you need to provide "secure" syntax in your host..
for e.g.
unsecured connection host : xxx.database.windows.net:1433
secured connection host : xxx.database.secure.windows.net:1443
Unfortunately there's no way, but you could use pyodbc.

Connecting to Microsoft SQL Server through pyODBC on Ubuntu

Am having an issue connecting to a Microsoft SQL Server instance from pyODBC within an Ubuntu (12.10) machine.
The error I am getting back is:
pyodbc.Error: ('IM002', '[IM002] [unixODBC][Driver Manager]Data Source name not found, and no default driver specified (0) (SQLDriverConnect)')
The connection string am using for pyodbc is:
self.corpus_cnxn = pyodbc.connect('DRIVER={FreeTDS};SERVER=UKEDN-06880;DATABASE=db1;UID=user;PWD=pass')
This seems to work fine from pyODBC within Windows (just need to change the DRIVER to 'SQL Server' instead of 'FreeTDS'), and it work fine when I try to connect from the Ubuntu machine using the tsql Tool from the terminal, with the following command:
tsql -S UKEDN-06880 -p 1433 -U user -P pass
I can select any table with no issues, it just doesn't seem to work from within pyODBC.
Any help or advice will be much appreciated, my Linux skills are uber weak and am totally stuck, although since it works from tsql I get the feeling that am very close!
It looks like you have gotten freeTDS to work correctly since you can use tsql. Have you tried to connect with isql?
Look at this howto for a detailed walk through. The part I think you need is in setting up unixodbc a little ways down the page.
first stape
$ sudo apt-get install libmdbodbc1
edit the file /etc/odbcinst.ini like this
[Microsoft Access Driver (*.mdb)]
Description = Microsoft Access Driver (*.mdb)
Driver = /path/to/file/libmdbodbc.so
Setup = /path/to/file/libtdsS.so
CPTimeout =
CPReuse =
And the file /etc/odbc.ini
[Microsoft Access Driver (*.mdb)]
Description = SQL Server
Driver = Microsoft Access Driver (*.mdb)
Trace = No
TraceFile = /tmp/mssodbc.log

Categories