Pyodbc – "Data source name not found, and no default driver specified"

Question:

I have trouble getting pyodbc work. I have unixodbc , unixodbc-dev, odbc-postgresql, pyodbc packages installed on my Linux Mint 14.
I am losing hope to find solution on my own, any help appreciated. See details below:

Running:

>>> import pyodbc
>>> conn = pyodbc.connect("DRIVER={PostgreSQL};SERVER=localhost;DATABASE=test;USER=openerp;OPTION=3;")

Gives me:

>>> pyodbc.Error: ('IM002', '[IM002] [unixODBC][Driver Manager]Data source name not found, and no default driver specified (0) (SQLDriverConnect)')

# odbcinst -j gives:

unixODBC 2.2.14
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /home/atman/.odbc.ini
SQLULEN Size.......: 4
SQLLEN Size........: 4
SQLSETPOSIROW Size.: 2

Which makes me think there is a unixodbc configuration problem.
Here are my unixodbc config file contents:

File /etc/odbcinst.ini:

[PostgreSQL ANSI]
Description     = PostgreSQL ODBC driver (ANSI version)
Driver      = psqlodbca.so
Setup       = libodbcpsqlS.so
Debug       = 0
CommLog     = 1
UsageCount      = 2

[PostgreSQL Unicode]
Description     = PostgreSQL ODBC driver (Unicode version)
Driver      = psqlodbcw.so
Setup       = libodbcpsqlS.so
Debug       = 0
CommLog     = 1
UsageCount      = 2

File /etc/odbc.ini :

[PostgreSQL test]
Description         = PostgreSQL 
Driver              = PostgreSQL ANSI
Trace               = No
TraceFile           = /tmp/psqlodbc.log
Database            = template1
Servername          = localhost
UserName            =
Password            =
Port                =
ReadOnly            = Yes
RowVersioning       = No
ShowSystemTables    = No
ShowOidColumn       = No
FakeOidIndex        = No
ConnSettings        =

File ~/.odbc.ini:

[DEFAULT]
Driver = PostgreSQL

[PostgreSQL]
Description         = Test to Postgres
Driver              = PostgreSQL
Trace               = Yes
TraceFile           = sql.log
Database            = nick
Servername          = localhost
UserName            =
Password            =
Port                = 5432
Protocol            = 6.4
ReadOnly            = No
RowVersioning       = No
ShowSystemTables    = No
ShowOidColumn       = No
FakeOidIndex        = No
ConnSettings        =
Asked By: atman

||

Answers:

I believe the answer to your problem is that in your ~/.odbc.ini file you are saying to use driver PostgreSQL – but you have not defined that driver in your /etc/odbcinst.ini file. Try changing PostgreSQL to PostgreSQL ANSI or PostgreSQL Unicode (both of which are defined in /etc/odbcinst.ini).

Answered By: Benny Hill

For me, the issue was the actual location of my odbc.ini and odbcinst.ini files.

On many systems, the install location of these files is in /etc/

However, in my case, these files were located under /usr/local/etc/

The could be determined by typing
odbcinst -j

Which yielded:

unixODBC 2.3.0
DRIVERS............: /usr/local/etc/odbcinst.ini
SYSTEM DATA SOURCES: /usr/local/etc/odbc.ini
FILE DATA SOURCES..: /usr/local/etc/ODBCDataSources
USER DATA SOURCES..: /usr/local/etc/odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8

My odbc.ini files already exists in /etc, so the solution was to copy them over over from /etc/ to /usr/local/etc/

cp /etc/odbc.ini /etc/odbcinst.ini /usr/local/etc/

Edit: It’s also worth noting that the path outputted by the odbcinst -j command can change depending on using sudo or not.

Answered By: tandy

For me, it was all down to a single whitespace character.

$cat /home/ec2-user/.odbc.ini
[DSNNAME]
Driver =FreeTDS
Description=description
Server =serverpath
Port =1433
Database =dbname

Gave me the “Data source name not found, and no default driver specified” error.

Removing all the whitespaces before the ‘=’ character made it work.

On a secondary note, using osql for DSN connection testing gives you a much more verbose description of any errors. It helped me a lot in the process.

$ osql -S DSNNAME -U username -P password
checking shared odbc libraries linked to isql for default directories...
    trying /txM ... no
    trying /tmp/sql ... no
    trying /tmp/sql ... no
    trying /w}H ... no
    trying /usr/loc ... no
    trying /tmp/sql.log ... no
    trying /home ... no
    trying /.odbc.ini ... no
    trying /usr/local/etc ... OK
checking odbc.ini files
    reading /home/ec2-user/.odbc.ini
[DSNNAME] found in /home/ec2-user/.odbc.ini
found this section:
    [DSNNAME]
    Driver =FreeTDS
    Description=description
    Server =serverpath
    Port =1433
    Database =dbname

looking for driver for DSN [DSNNAME] in /home/ec2-user/.odbc.ini
  no driver mentioned for [DSNNAME] in .odbc.ini
looking for driver for DSN [default] in /home/ec2-user/.odbc.ini
osql: error: no driver found for [DSNNAME] in .odbc.ini

Comparing the error message against my ini file made triaging the issue a lot easier.

Answered By: Andy G

For others troubleshooting this same generic error, ensure that you didn’t accidentally add extraneous characters at the top of your odbc.ini file – which causes it to be invalid and all data-source declarations to be silently ignored (the error giving no indication of the specific problem).

Answered By: DavidJ

I have the same problem. It turns out that the data source file missed: /etc/ODBCDataSources. Just touch that file and it works.

Answered By: yzark

For me, I found this problem was due to mixing 32-bit and 64-bit binaries. All I can say in regards to fixing that is "Good luck, and try to keep it all 32 or all 64."

Explanation, since it was asked for:

Basically, we bundled the app with a 32 bit binary that we were using. We had no way to get a 64 bit version of that proprietary binary (we used and distributed it with their permission ofc). The binary file was a .dll file.

If a 64 bit binary (such as an .exe) imports a .dll it assumes things about where the runnable code and other assets (like strings) are inside of that binary. When a 64 bit imports a 32 bit, and the 64 bit hasn’t been properly configured, it will assume the wrong location as an instruction takes up a different amount of space, and is therefore a different number of bits into the file.

It can also be problematic if the 32 bit binary shares any memory with the 64 bit (which it does, for sure) as even basic types like numbers can vary in size (in bits) between the two.

I’d go into more detail about my specific scenario, but it was closed-source software, I’m not on the team anymore, and it seems sortof trade-secret-ish.

Answered By: Lazerbeak12345