简体   繁体   中英

pyodbc + PostgreSQL ODBC: connection string works, DSN doesn't

I am trying to connect to a Postgres DB built for a Django app. I can connect fine in windows, but when we moved it over to a Linux server for production it stopped working. I tracked it down to pyodbc not working. So in a separate script, I have been trying to get a connection working with no luck. I'm pretty sure the Linux server is running Redhat (yum is the install, but I can double check if it matters)

Here are some of the things I have tried: installed unixODBC-devel

added a DSN to the user sourcename /home/localUsername/.odbc.ini file as follows:

[DSNName]
Description=Postgres Connection to Database
Driver=/usr/pgsql-10/lib/psqlodbc.so
Server=servername
Database=dbname
PWD=pass
UID=username

Running odbcinst -q -d returns: [PostgreSQL]

python script I have tried (although using interpreter for now)

con = odbc.connect("DSN=DSNName")
con = odbc.connect("Driver={PostgreSQL};Uid=username;Pwd=pass; Server=servername;Port=5432)
con = odbc.connect("Driver={PostgreSQL Unicode(x64)};Uid=username;Pwd=pass; Server=servername;Port=5432)

I get one of three errors depending on which driver I try: For the Driver using Unicode(x32) I get:

pyodbc.Error ('01000', "[01000] [unixODBC][Driver Manager]can't open lib 'PostgreSQL Unicode(x32)' : file not found ...

I figure that means this driver is not installed which is fine.

For the DSN approach I get:

pyodbc.OperationalError: ('08001', '[08001] FATAL: role:"localUsername" does not exists\n (101) (SQLDriverConnect)')

This second error seems to make me think (maybe incorrectly) that it is trying to use my localUsername to authenticate to Postgres, when I want to use a special admin username that was setup for the host for now.

For the third option (PostgreSQL):

pyodbc.OperationalError 08001 FATAL: database "dbname" does not exist

I don't understand why that might be? My first thought is Linux wants to use a different port for connection. Locally on windows I can use the 5432 port and it worked fine. So I'm at a loss on how to get it to find the DB assuming the rest is working okay.

If you need additional details let me know and I'll try to add them.

Edit: Have python (and Django) on one server. DB is on another.

Tried running psql -h OSServername -U 'username' with the same: role error/DB not found errors. I feel like I must be needing something after OSServername like 'OsServername/pgAdminServer' but that didn't work

where db 'username' is found by right clicking inside of pgAdmin one of the DB server names and selecting properties. Are the Server names inside pgAdmin different and do I need to somehow use the pgAdmin Server Name as part of the connection string?

As the comments suggest, starting with the psql -h command seems like a good place to start as it gets rid of the python complexity. Once I can get that command working, I might be able to fix the rest. What do I type when my Linux server name (Host name) is 'LinuxName', pgAdmin Server is 'pgAdminServer', the actual DB has a name 'dbName', and the pgAdmin username is 'username'. 'dbName' has an owner 'owner' which is different from the username of the pgServer as well as different from the Linux username I am signed in as. I also validated that the 'pgAdminServer' shows port 5432, so that shouldn't be the issue.

Edit 2: I got the pyodbc.connect('Driver={PostgreSQL};Server=servNm;Uid=uid;pwd=pwd;Database=db') to work. Now just need the last step for the DSN approach. Your dump_dsn worked to find a typo in my dsn file (.odbc.ini in my local home directory). So that helped. Still not finding the DB. File in: /etc/odbcinst.ini list the following drivers which I have tried all three in my DSN file:

/usr/pgsql-10/lib/psqlodbc.so
/usr/pgsql-10/lib/psqlodbca.so
/usr/pgsql-10/lib/psqlodbcw.so

here is the info again from my.odbc.ini file in home/user/.odbc.ini: variables: servNm, uid, db, and pwd match exactly with those found in my pyodbc.connect() string now working.

[DSNName]
Description=Postgres Connection to Database
Driver=/usr/pgsql-10/lib/psqlodbc.so
Server=servNm
CommLog=0
Debug=0
Fetch=100
UniqueIndex=1
UseDeclareFetch=0
Database=db
UID=uid
Username=uid
PWD=pwd
ReadOnly=0

Deleting and re-creating the ~/.odbc.ini file appears to have resolved the issue. This makes us suspect that there were one or more unusual characters in the previous version of that file that were causing strange behaviour.

One possible source of such troublesome (and sometimes even invisible.) characters is when copying text from the web. If we copy the following from our web browser …

DRIVER=PostgreSQL Unicode

… and paste it into a blank document in our text editor with the default encoding UTF-8 then everything looks normal. However, if we save that file (as UTF-8) and open it in a hex editor we can see that the space is not a normal space (U+0020) …

在此处输入图像描述

… it is a NO-BREAK SPACE (aka "NBSP", U+00A0, \xc2\xa0 in UTF-8 encoding) so the chances are very good that we would get an error when trying to use that DSN because b'PostgreSQL\xc2\xa0Unicode' is not the same as b'PostgreSQL Unicode' .

I had the exact same problem. I looked for several solutions, but none worked.

The problem was solved more easily than I thought:

1 - Remove all packages about postgresodbc:

$ sudo apt-get remove odbc-postgresql

2 - Install two libs, in the same order below:

$ apt-get install libcppdb-postgresql0 odbc-postgresql

Enjoy!

Doing so worked perfectly here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM