Connecting to Microsoft SQL Server through pyODBC on Ubuntu - python

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

Related

Error when trying to use pyobdc to connect a SQL Server in a Flask-Python Application on Azure App Service

I am developing a web application using Python and Flask.
My application accesses a Microsoft SQL Server using pyobdc. It runs locally.
When I deployed it to Azure App Service and used the application it would crash when it needed to access the server, giving me this error:
pyodbc.Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib 'ODBC Driver 17 for SQL Server' : file not found (0) (SQLDriverConnect)")
Random Details:
Azure Python Version: 3.8.12
Linux Details: Debian GNU/Linux 9 (stretch)
I tried using the kudu bash terminal in my Azure App Service to manually install it using the instructions in this ODBC driver linux link. But when I try, it tells me that sudo is not a command. (Is this an issue regarding Azure limitations or IT Permissions?)
I have also tried upgrading to ODBC Driver 18 for SQL Server to no avail.
I have read in some places that Microsoft Azure App Services does not support ODBC nor the installation of it.
Is this true? Is there a way around this issue?
And are there any alternative methods connecting the MS SQL Server to a python flask web app deployed on azure?
I have also checked the odbc.ini and odbcinst.ini files in /etc, and found that they were empty.
Okay I solved my issue.
I installed the ODBC Driver 17 for SQL Server via the dockerfile. I used the instructions on how to install found here using the ODBC 17 Debian version. But it didn't fully work because of some error so I modified slightly.
This is what I added to my docker:
#What I added to deal with the errors I was getting:
RUN apt-get update -y
RUN apt install unixodbc -y
#Installation instructions from microsoft link:
RUN su
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/debian/9/prod.list > /etc/apt/sources.list.d/mssql-release.list
RUN exit
RUN apt-get update
RUN ACCEPT_EULA=Y apt-get install -y msodbcsql17
RUN ACCEPT_EULA=Y apt-get install -y mssql-tools
#Checking the installation
RUN cat /etc/odbcinst.ini
#Create the odbc.ini file
RUN echo -e '[voip]\nDescription = whatever\nDriver = ODBC Driver 17 for SQL Server\nServer = whatever\nUser = whatever\nPassword = whatever\nPort = whatever\nDatabase = whatever' > odbc.ini
#Moving odbc.ini to the etc directory
RUN mv odbc.ini etc
#Checking contents of odbc.ini
RUN cat /etc/odbc.ini
I had to edit the odbc.ini myself because it was empty. But the odbcinst.ini should be populated after running the commands provided by the microsoft instructions.
etc/odbcinst.ini should have something like this:
[ODBC Driver 17 for SQL Server]
Description=Microsoft ODBC Driver 17 for SQL Server
Driver=/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.10.so.1.1
UsageCount=1
etc/odbc.ini should look something like this:
[voip]
Description = whatever
Driver = ODBC Driver 17 for SQL Server
Server = whatever
User = whatever
Password = whatever
Port = whatever
Database = whatever
You'll have to edit the odbc.ini yourself if you have this issue. But what I did was create an odbc.ini file. And then moved it into /etc.

Pyodbc driver/DSN not found AWS lambda - works on EC2

I am trying to connect to SQL Server using PYODBC inside AWS Lambda. I set up an EC2 instance and installed all dependencies and packages needed. I am able to query SQL within EC2 but not within Lambda.
Seems like I am missing a config or a library to set up the connections when packaging. I have copied the SQL driver in /opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.3.so.1.1 location. Copied the odbc.ini and odbcinst.ini files as needed. Copied the libtds and libodc* as well.
The error that I get when I package all the libraries and dependencies into lambda package is below:
[IM002] [unixODBC][Driver Manager]Data source name not found, and no default driver specified (0) (SQLDriverConnect)
My odbc.ini and odbcinst.ini is below:
odbc.ini
[DEV]
Driver = ODBC Driver 17 for SQL Server
Description = DEV
Trace = No
Server = abc.net,1234
odbcinst.ini
[ODBC Driver 17 for SQL Server]
Description=Microsoft ODBC Driver 17 for SQL Server
Driver=/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.3.so.1.1
UsageCount=1
I tried providing the DSN and also explicitly mentioning the Driver and Server name in pyodbc.connect. Still no luck!
Any help or direction would be appreciated!
TIA
After digging through multiple blogs and links, the answer is as simple as explicitly mentioning the location of driver when you connect using pyodbc.
conn = pyodbc.connect('Driver=msodbcsql17/lib64/libmsodbcsql-17.3.so.1.1;Server=server,port;UID=uname;PWD=pwd;database=db_name;Encrypt=YES;TrustServerCertificate=Yes')

Error : connecting to Azure SQL DB from VM in Google cloud using pypyodbc

I am having issues connecting to an Azure database from a Virtual Machine running Ubuntu 16.04. This VM is in Google cloud. I get the following error
pypyodbc.Error: (u'IM002', u'[IM002] [unixODBC][Driver Manager]Data source
name
not found, and no default driver specified')
This code works fine locally on my PC in a Jupyter notebook. I have added the Google Cloud VM's IP address to the let it through the Azure firewall- so that doesn't appear to be the cause of the error. I have observed that I can replicate the original error message in Jupyter notebook if I change the driver "SQL Server Native Client" from 11.0 to 13.0
This all points to driver issues. A similar issue has been discussed here
With the problem being linked to "not defining that driver in the "/etc/odbcinst.ini" file."
My odbcinst.ini file contains the following information:
[ODBC Driver 13 for SQL Server]
Description=Microsoft ODBC Driver 13 for SQL Server
Driver=/opt/microsoft/msodbcsql/lib64/libmsodbcsql-13.1.so.8.0
UsageCount=1
My odbc.ini file contains no information.
If I change my connection string in my code to "Driver={SQL Server Native Client 13.0" I get the same error. My other thought was to run with a version 11 of the driver. However there doesn't appear to be one for Ubuntu (only SUSE & RedHat Linux).I am new to this subject area- so feeling stuck. Any suggestions on a next logical step to resolve the connection issue.
Regards
Mike

Pyodbc can't find FreeTDS driver

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.

Azure SQL Server and FreeTDS ODBC with linux and windows dev environments

I host a web app on Windows Azure (Flask), which runs on Windows Server.
I have a linux development environment (some other contributors may use windows in the future), so we use pyodbc to communicate with the SQL Server. Unfortunately, I have to change my connection string every time I pull or push from the Azure deployment due to linux and windows ODBC connection differences.
Consider my connection string:
pyodbc.connect('Driver=SQL
Server;Server=tcp:mydbname.database.windows.net,1433;Database=mydbname;Uid=dbuser#mydbname;Pwd=topsecret;Encrypt=yes;TrustServerCertificate=no;Connection
Timeout=30;')
This works fine once it's deployed on the server (Windows Server), or on the windows box, but doesn't work on the linux dev box. I found some over SO questions and a guide on how to setup FreeTDS (e.g. Connecting to Microsoft SQL Server through pyODBC on Ubuntu and http://www.gazoakley.com/content/connecting-sql-azure-python-ubuntu-using-freetds-and-unixodbc, http://blog.tryolabs.com/2012/06/25/connecting-sql-server-database-python-under-ubuntu/).
However, after following those guides through you have to remove the server name and replace it with a the DSN (data source name), which is a locally configured variable. While that will work on a local linux box, that doesn't work once it's deployed to the Azure web server (windows).
pyodbc.connect('DSN=SQL Server;Driver=SQL
Server;Database=mydbname;Uid=dbuser#mydbname;Pwd=topsecret;Encrypt=yes;TrustServerCertificate=no;Connection
Timeout=30;')
You have to remove the servername otherwise it conflicts with the odbc/FreeTDS config.
With no DNS specified (first connection string in this post):
pyodbc.Error: ('IM002', '[IM002] [unixODBC][Driver Manager]Data source
name not found, and no default driver specified (0) (SQLDriverConnect)
With DNS and servername:
pyodbc.Error: ('HY000', '[HY000] [unixODBC][FreeTDS][SQL Server]Only
one between SERVER, SERVERNAME and DSN can be specified (0)
(SQLDriverConnect)')
With DNS and no server name
When deployed to the server it wont work.
We use git for version control, and I don't want to have continuous merge conflicts as developers change their connection string to match their dev enviroments and/or deploy to the Azure site.
Is there a clean fix for this. Gut tells me I'm doing something wrong, and this is very trivial.
First of all, if you have successfully connected to SQL Server both in Windows and Linux platforms, congratulations. In python, there is a package installed by python default named ‘platform’, we can use it to check the what platform python script run in. And we can set 2 connection string in advance, and select the specific string in different platform.
Here is my python code snippet:
import platform
def getOBCDString():
stsos = platform.system()
bol = False
odbcstring=''
if(stsos == "Windows"):
bol = True
odbcstring = 'windows_odbc_string'
elif(stsos == "Linux"):
bol = True
odbcstring = 'Linux_odbc_string'
#else:
# custom error handle
return (bol,odbcstring)
bol,string = getOBCDString()
if(bol):
print(string)

Categories