Pyodbc - "数据源未找到且未指定默认驱动程序"

49

我遇到了使用pyodbc的问题。我在Linux Mint 14上安装了unixodbcunixodbc-devodbc-postgresqlpyodbc软件包。

我已经失去了自行解决问题的希望,非常感谢任何帮助。以下是详细信息:

运行:

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

给了我:

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

# odbcinst -j 给出以下信息:

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

这让我想到可能存在一个unixodbc配置问题。这是我的unixodbc配置文件内容:

文件 /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

文件 /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        =

文件 ~/.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        =

1
你需要尝试这个:...你可能需要从/etc/odbc.ini复制/usr/local/etc/odbc.ini和从/etc/odbcinst.ini复制/usr/local/etc/odbcinst.ini(至少这是我的经验,可能是因为unixODBC已经随我的Linux发行版安装好了)。 - Murugan C
6个回答

25

我认为你问题的答案在于你的~/.odbc.ini文件中,你使用了PostgreSQL驱动器 - 但是你没有在/etc/odbcinst.ini文件中定义该驱动器。尝试将PostgreSQL更改为PostgreSQL ANSIPostgreSQL Unicode(两者都在/etc/odbcinst.ini中定义)。


请问您能否在这里提供一个示例?我是应该直接将“PostgreSQL”替换为“PostgreSQL Unicode”,还是替换为“psqlodbcw.so”? - user1841829
尝试直接将PostgreSQL替换为PostgreSQL UnicodePostgreSQL ANSI - Benny Hill
1
尝试过了,还在/etc/odbcinst.ini中添加了驱动程序文件的完整路径,但没有效果,仍然是一样的... - user1841829
1
摆脱您的~/.odbc.ini配置文件,并将连接字符串更改为conn = pyodbc.connect("DRIVER={PostgreSQL test};SERVER=localhost;DATABASE=test;USER=openerp;OPTION=3;") - Benny Hill
你之前完全正确,我的错误在于执行了相同的Python语句(必须将DRIVER={PostgreSQL}更改为DRIVER={PostgreSQL Unicode}),现在一切都正常了。非常感谢你。 - user1841829
谢谢,@BennyHill。你的对话帮助我解决了我的问题。 - Ajay Chauhan

19

对我而言,问题在于我的odbc.ini和odbcinst.ini文件的实际位置。

在许多系统上,这些文件的安装位置在/etc/中。

然而,在我的情况下,这些文件位于/usr/local/etc/目录下。

可以通过输入以下命令确定它们的位置:
odbcinst -j

该命令将输出:

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

我的odbc.ini文件已经存在于/etc目录中,所以解决方法是将它们从/etc/复制到/usr/local/etc/。

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

编辑:值得注意的是,使用sudo与否可能会导致odbcinst -j命令输出的路径发生变化。


谢谢您的回复,但我有一个问题。这个修复方法对我有效,即使我在我的代码中使用了os.environ["ODBCINI"]="/etc/odbc.ini"和os.environ["ODBCSYSINI"]="/etc/odbcinst.ini"。似乎由于/etc/<odbc files>是由root拥有的(当运行sudo odbcinst -j时显示的位置),程序忽略了这些文件(因为它不是以root身份运行)。这对我来说很奇怪,因为odbc文件具有公共读取权限。您知道这是怎么回事吗? - lampShadesDrifter

5
对我而言,问题仅仅存在于一个空格字符上。
$cat /home/ec2-user/.odbc.ini
[DSNNAME]
Driver =FreeTDS
Description=description
Server =serverpath
Port =1433
Database =dbname

我遇到了“数据源名称未找到,且未指定默认驱动程序”的错误。

去掉所有'='字符前面的空格后,问题得以解决。

另外,使用osql进行DSN连接测试可以获得更详细的错误描述。在此过程中,它对我非常有帮助。

$ 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

将错误消息与我的ini文件进行比较,使问题的排除变得更加容易。


1

对于其他遇到相同问题的人,请确保您没有在odbc.ini文件顶部意外添加多余字符,这会使其无效,并且所有数据源声明将被静默忽略(错误不会指示具体问题)。


1
对于我来说,我发现这个问题是由于混合使用32位和64位二进制文件导致的。关于解决这个问题,我只能说“祝你好运,并尽量保持所有都是32位或64位。”

解释,因为有人要求:

基本上,我们将应用程序与我们正在使用的32位二进制文件捆绑在一起。我们无法获得该专有二进制文件的64位版本(当然,我们使用并分发它是经过他们许可的)。二进制文件是一个.dll文件。
如果64位二进制文件(例如.exe)导入.dll文件,则假定其中可运行代码和其他资源(如字符串)的位置。当64位导入32位时,并且64位未正确配置,则会将错误位置视为指令占用不同数量的空间,因此位于文件中的位数也不同。
如果32位二进制文件与64位共享任何内存(肯定会),则也可能会出现问题,因为即使像数字这样的基本类型在两者之间的大小(以位为单位)也可能有所不同。

我可以进一步详细说明我的具体情况,但这是闭源软件,我已经不在团队中了,而且似乎有点商业机密。


你能再详细解释一下吗? - Pat
1
@Pat那个编辑有帮助吗? - Lazerbeak12345

1
我有同样的问题。原来数据源文件丢失了:/etc/ODBCDataSources。只需创建该文件即可解决问题。

这个字典里应该有哪个文件? - Pat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接