Jupyter: can't connect to MS SQL Server with pyodbc - python

I can't connect to MS SQL Server in my Jupyter notebook:
Code:
import pyodbc
pyodbc.drivers()
Output:
[]
Nothing!
Connection string:
db_connection = pyodbc.connect('Driver={ODBC Driver 17 for SQL Server};'
'Server=Server IP;'
'Database=DB_Main;'
'UID=DB_User;'
'PWD=secrets')
Every conceivable driver string I use I get the same basic message:
Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib
'ODBC Driver 17 for SQL Server' : file not found (0)
(SQLDriverConnect)")
Since pyodbc.drivers() isn't showing anything it would seem that the installation is borked.
UPDATE:
I was unable to get the symlink solutions with the INI files to work as suggested here: Can't open lib 'ODBC Driver 13 for SQL Server'? Sym linking issue?
Directly specifying the driver as shown in the answer below is what worked.

I ended up having to directly specify the driver like this:
driver = '/usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so'
ip = "10.10.10.1"
db_connection = pyodbc.connect(
driver = driver,
Server = ip,
Port = "49189",
Database = "project_db",
UID = "db_user",
PWD = "secrets" )
Installed TDS and the ODBC packages on the server then searched for the libtdsodbc.so driver using find. This worked perfectly though there may be other simpler ways.

Try Installing ODBC Drivers (13/17) and your pyodbc.drivers() should return the driver info, you should be able connect then.

Related

OperationalError when trying to connect to SQL Server database using pyodbc

I'm trying to connect to a SQL server database using pyodbc in Python 3. But I get an error when I'm trying to establish the connection.
I do something like this:
import pyodbc
conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};Server=192.168.2.250;Database=DB;UID=username;PWD=password;')
And I get this:
OperationalError: ('08001', '[08001] [Microsoft][ODBC Driver 18 for SQL Server]SSL Provider: [error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol][error:140B40C7:SSL routines:SSL_do_handshake:peer did not return a certificate] (-1) (SQLDriverConnect)')
Does anybody know how to solve this? The database is not my own, so I hope there is a solution that doesn't require changing any settings there.
I'm running Ubuntu within the Windows Subsystem for Linux.
There is a breaking change in ODBC Driver 18 for SQL Server
Similar to the HTTP to HTTPS default changes made in web browsers a few years back (and the security reasons for them), we are changing the default value of the Encrypt connection option from no to yes/mandatory.
ODBC Driver 18.0 for SQL Server Released
So this
conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};Server=192.168.2.250;Database=DB;UID=username;PWD=password;')
is the same as
conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};Server=192.168.2.250;Database=DB;UID=username;PWD=password;Encrypt=yes')
If you don't want an encrypted connection you must opt out:
conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};Server=192.168.2.250;Database=DB;UID=username;PWD=password;Encrypt=no')
We also changed the behavior of TrustServerCertificate to not be tied to the Encrypt setting
So if your server is using a self-signed certificate, you also must opt out of certificate validation. so
conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};Server=192.168.2.250;Database=DB;UID=username;PWD=password;Encrypt=no;TrustServerCertificate=yes')
I ended up taking my script out of WSL. Running the same command (with David's additions or ODBC Driver 17 for SQL Server instead of 18) under Windows works without issues in my case.

pyodbc connection string isn't working - "Data source name not found and no default driver specified"

Recently I'm trying to connect to a SQL Server though pyodbc but I'm having some troubles with the connection string. I already tried as suggested on this previous question: Pyodbc error Data source name not found and no default driver specified paradox, creating a .dsn file and trying to implement the procedure's output on the string, but stil get the same error message: ('IM002', '[IM002] [unixODBC][Driver Manager]Data source name not found, and no default driver specified (0) (SQLDriverConnect)')
This is what I'm doing so far:
conn = pyodbc.connect('DRIVER={ODBC Driver 13 for SQL Server};
'WSID={BRRIO-xxxx};'
'APP={Microsoft® Windows® Operating System};'
'Trusted_Connection=Yes;'
'SERVER=BRRIO-xxxx\xxx;'
'Database=xxx_Data;'
'UID="xxxx";'
'PWD="xxxx";'
)
and this is what my .dsn file looks like:
DRIVER={ODBC Driver 13 for SQL Server};
WSID={BRRIO-xxxx};
APP={Microsoft® Windows® Operating System};
Trusted_Connection=Yes;
SERVER=BRRIO-xxxx\xxx
Any help is really appreciated!
For anyone who's having some troubles with this, I found the solution following the steps here: https://www.sqlserverlogexplorer.com/database-does-not-exist-access-denied/
Basically for me it was a firewall problem, where the port 1433 was blocked. Also, make sure you are using the correct driver for you case (pyodbc.drivers(), as suggested by #Gord Thompson) and check for remote server connections on yours SQL Server (SQL Server Management Studio > Go to SQL Server instance property > Connections > check Allow remote connection to this server).

pyodbc.connect - works from one computer but not another

I have been running Python script using my desktop at work that successfully connects to a remote desktop server and outputs data in SQL via pyodbc.connect.
I am looking to migrate this code to a separate remote desktop PC recently installed at work and I get the following error:
InterfaceError: ('IM002', '[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)')
The code I am using is:
cnxn = pyodbc.connect("Driver={SQL Server Native Client 11.0};"
"Server=AUBAMTRAS01-DEV;"
"Database=ForwardTrading;"
"Username=xxxxxxxx;"
"Password=yyyyyyyy;"
"Trusted_Connection=yes;")
cursor = cnxn.cursor()
cursor.execute('SELECT distinct(Commodity) from ForwardCurvesOilAndGas')
for row in cursor:
print('row = %r' % (row,))
Data source name not found and no default driver specified
This means you need to install the SQLDriverConnect driver on your second machine.
SOLVED - Driver required was 'SQL Server' not 'SQL Server Native Client 11.0'

Connecting to SQL Server named instance from Linux using pyodbc

I'm currently trying to connect to a SQL Server (that I don't have visibility into, but have credentials for) using PyODBC. The code that I have works on my Windows desktop, but does not work when moved onto my RedHat Linux machine. I need it on Linux in support of a project.
Here's what I have:
server = 'tcp:myserver\inst1'
database = 'mydatabase'
username = 'myusername'
password = 'mypassword'
cnxn = pyodbc.connect('DRIVER={ODBC Driver 13 for SQL Server};SERVER=' + server + ';DATABASE=' + database + ';UID=' + username + ';PWD=' + password)
And here is the error I'm getting:
pyodbc.OperationalError: ('HYT00', u'[HYT00] [unixODBC][Microsoft][ODBC Driver 13 for SQL Server]Login timeout expired (0) (SQLDriverConnect)')
The one difference between the Windows version and Linux version is the driver portion. Windows uses '{SQL Server}' while the Linux version uses '{ODBC Driver 13 for SQL Server}'.
In my /etc/odbcinst.ini file, I have 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.9.1
UsageCount=1
Anyone have any suggestions?
Unlike the Windows versions of Microsoft's ODBC Drivers for SQL Server, the Linux versions of those drivers are unable to resolve SQL Server instance names. So on a Windows client we can use the following (provided that the SQL Browser service is running on the server)
cnxn = pyodbc.connect(
"Driver=ODBC Driver 17 for SQL Server;"
r"Server=myserver\SQLEXPRESS;"
# and so on
)
but that won't work on Linux. However we can use the sqlserverport module (which I maintain) to retrieve the port number from the SQL Browser service:
import pyodbc
import sqlserverport
servername = "myserver"
serverspec = f"{servername},{sqlserverport.lookup(servername, 'SQLEXPRESS')}"
conn = pyodbc.connect(
"Driver=ODBC Driver 17 for SQL Server;"
f"Server={serverspec};"
# and so on
Use the driver path instead of the driver name. In your example take the full /opt/microsoft/msodbcsql/lib64/libmsodbcsql-13.1.so.9.1
use IP address and port number instead of name/instancename.
execute this query to have the real port number:
SELECT DISTINCT local_net_address, local_tcp_port FROM sys.dm_exec_connections
and then datasrc=N'192.168.1.112,61423'

pyodbc error on OS X machine?

I'm trying to do access the remote MS-SQL database from my OS X machine, with help of pyodbc and python. When I try to execute, it's showing an error like this
Error: ('IM002', '[IM002] [unixODBC][Driver Manager]Data source name not found, and no default driver specified (0) (SQLDriverConnect)')
The code I've written is:
import pyodbc
def createdatabase():
driver = 'SQL Server'
server = '00000000'
db1 = 'Vodafone'
tcon = 'yes'
uname = 'user'
pword = 'pwd'
cnxn = pyodbc.connect(driver='{SQL Server}', host=server,database=db1,trusted_connection=tcon, user=uname, password=pword)
cursor = cnxn.cursor()
This may not be your only problem, but the pyodbc.connect() string needs to be formed with semicolons like this:
DRIVER={FreeTDS};SERVER=yoursqlserver.com;PORT=1433;DATABASE=yourdb;UID=youruser;PWD=yourpass;TDS_Version=7.2;
You'll also have to read up on setting up FreeTDS and unixODBC from a Mac. If you're specifying SQL Server instead of FreeTDS, I'm guessing you haven't set up your configuration in freetds.conf, odbc.ini and odbcinst.ini, which are required for connecting to SQL Server from non-Windows machines.

Categories