Goal: Connect to remote MSSQL 2016 server via Python.
Main approach: Closely followed tutorial in https://github.com/mkleehammer/pyodbc/wiki/Connecting-to-SQL-Server-from-Mac-OSX .
Problem: Able to connect via tsql, but isql is not working. Errors
[S1000][unixODBC][FreeTDS][SQL Server]Unable to connect to data source
[37000][unixODBC][FreeTDS][SQL Server]Login failed for user 'DOMAIN\user-p'
[37000][unixODBC][FreeTDS][SQL Server]Cannot open database "TIT_BI_OPERATIONS" requested by the login. The login failed.
Things tried:
Different ODBC drivers 13.1, 17, FreeTDS
Inclusion/exclusion of escape character in the user name.
Host name vs host ip.
Settings:
odbc.ini
[ODS_DSN]
Description = Connection to ODS MS_SQL 2016
Driver = FreeTDS
Servername = ODS_DSN
Port = 40000
Database = TIT_BI_OPERATIONS
odbcinst.ini
[FreeTDS]
Driver=/usr/local/lib/libtdsodbc.so
Setup=/usr/local/lib/libtdsodbc.so
UsageCount=1
freetds.conf
[ODS_DSN]
host = 164.10.17.77
port = 40000
tds version = 7.4
client charset = UTF-8
Notes:
Even though, its not very promising to run python without connecting through tsql and isql first, i still tried without success. Using pyodbc, pypodbc, sqlalchemy.
Most errors in the form: Login failed for user 'DOMAIN\user-p'
For ODBC driver 13: Can't open lib '/usr/local/lib/libmsodbcsql.13.dylib'
I am able to connect via SQL PRO STUDIO, using exact same credentials.
If you have any thoughts which direction to go to climb out of this connection problem, it would be greatly appreciated. Thank you!
If you're using Windows domain auth, you'll have to use FreeTDS. Oddly enough, Windows domain auth isn't supported by the Microsoft ODBC Driver, only FreeTDS.
Since you can connect with the tsql command, that means FreeTDS is working. I'd recommend connecting directly from Python explicitly. Try a connection string like this:
import pyodbc
con = pyodbc.connect(
r"DRIVER={FreeTDS};"
r"SERVER=164.10.17.77;"
r"PORT=40000;"
r"DATABASE=TIT_BI_OPERATIONS;"
f"UID=DOMAIN\\user-p;"
f"PWD=yourpassword;"
r"TDS_Version=7.3;"
)
cursor = con.cursor();
cursor.execute("SELECT 'this' AS that")
for row in cursor.fetchall():
print(row)
Note that you do need two backslashes in the UID field to connect with Windows domain auth; that is not a typo!
Related
I am trying to use Python to connect to a SQL database by using Window authentication. I looked at some of the posts here (e.g., here), but the suggested methods didn't seem to work.
For example, I used the following code:
cnxn = pyodbc.connect(driver='{SQL Server Native Client 11.0}',
server='SERVERNAME',
database='DATABASENAME',
trusted_connection='yes')
But I got the following error:
Error: ('28000', "[28000] [Microsoft][SQL Server Native Client 11.0][SQL Server]
Login failed for user 'DOMAIN\\username'. (18456) (SQLDriverConnect); [28000] [Microsoft]
[SQL Server Native Client 11.0][SQL Server]Login failed for user 'DOMAIN\\username'.
(18456)")
(Note that I replaced the actual domain name and user name with DOMAIN and username respectively, in the error message above.)
I also tried using my UID and PWD, which led to the same error.
Lastly, I tried to change the service account by following the suggestion from the link above, but on my computer, there was no Log On tab when I went to the Properties of services.msc.
I wonder what I did wrong and how I can fix the problem.
Connecting from a Windows machine:
With Microsoft's ODBC drivers for SQL Server, Trusted_connection=yes tells the driver to use "Windows Authentication" and your script will attempt to log in to the SQL Server using the Windows credentials of the user running the script. UID and PWD cannot be used to supply alternative Windows credentials in the connection string, so if you need to connect as some other Windows user you will need to use Windows' RUNAS command to run the Python script as that other user..
If you want to use "SQL Server Authentication" with a specific SQL Server login specified by UID and PWD then use Trusted_connection=no.
Connecting from a non-Windows machine:
If you need to connect from a non-Windows machine and the SQL Server is configured to only use "Windows authentication" then Microsoft's ODBC drivers for SQL Server will require you to use Kerberos. Alternatively, you can use FreeTDS ODBC, specifying UID, PWD, and DOMAIN in the connection string, provided that the SQL Server instance is configured to support the older NTLM authentication protocol.
I tried everything and this is what eventually worked for me:
import pyodbc
driver= '{SQL Server Native Client 11.0}'
cnxn = pyodbc.connect(
Trusted_Connection='Yes',
Driver='{ODBC Driver 11 for SQL Server}',
Server='MyServer,1433',
Database='MyDB'
)
Try this cxn string:
cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;PORT=1433;DATABASE=testdb;UID=me;PWD=pass')
http://mkleehammer.github.io/pyodbc/
I had similar issue while connecting to the default database (MSSQLSERVER). If you are connecting to the default database, please remove the
database='DATABASENAME',
line from the connection parameters section and retry.
Cheers,
Deepak
The first option works if your credentials have been stored using the command prompt. The other option is giving the credentials (UId, Psw) in the connection.
The following worked for me:
conn = pyodbc.connect('DRIVER={SQL Server};SERVER=yourServer;DATABASE=yourDatabase;UID=yourUsername;PWD=yourPassword')
import pyodbc #For python3 MSSQL
cnxn = pyodbc.connect("Driver={SQL Server};" #For Connection
"Server=192.168.0.***;"
"PORT=1433;"
"Database=***********;"
"UID=****;"
"PWD=********;")
cursor = cnxn.cursor() #Cursor Establishment
cursor.execute('select site_id from tableName') #Execute Query
rs = cursor.fetchall()
print(rs)
A slightly different use case than the OP, but for those interested it is possible to connect to a MS SQL Server database using Windows Authentication for a different user account than the one logged in.
This can be achieved using the python jaydebeapi module with the JDBC JTDS driver. See my answer here for details.
Note that you may need to change the authentication mechanism. For example, my database is using ADP. So my connection looks like this
pyodbc.connect(
Trusted_Connection='No',
Authentication='ActiveDirectoryPassword',
UID=username,
PWD=password,
Driver=driver,
Server=server,
Database=database)
Read more here
Trusted_connection=no did not helped me. When i removed entire line and added UID, PWD parameter it worked. My takeaway from this is remove
I'm attempting to connect to a local instance of SQL Server running on my machine. I am able to connect to a local instance with this code from our server, but it fails on my local machine.
I've enabled named pipes and all the ips in the SQL Server configuration.
The code I'm using is as follows:
from pymssql import connect
server = r'.\SQLEXPRESS2014' # I've also tried MORGANT-PC\SQLEXPRESS and SQLEXPRESS2014
username = 'MyUserName'
password = 'MyPassword'
master_database_name = 'SuperSecretDatabase'
port = 5000
server_args = {'host': server, 'user': username, 'password': password,
'database': master_database_name, 'port': port} # I've tried having the first key be both host and server, because pymssql's docs are unclear on the difference.
master_database = connect(**server_args)
If I use the instance name, I get this error:
pymssql.InterfaceError: Connection to the database failed for an unknown reason.
I set the port to 5000 so that I could try connecting to it with
server = 127.0.0.1
port = 5000
which fails with the slightly different error message:
pymssql.OperationalError: (20009, b'DB-Lib error message 20009, severity 9:\nUnable to connect: Adaptive Server is unavailable or does not exist\nNet-Lib error during Unknown error (10035)\n')
I've read a bunch of answers here on SO, and most of them seem to indicate it's an issue with FreeTDS, but I'm on Windows 8.1, so I don't have FreeTDS.
I've tried connecting with sqlcmd with the host\instance name and that works fine. It also works in SSMS.
I've tried passing .\SQLEXPRESS2014 to both the host and server parameter in pymssql.connect() and they both fail with the same aforementioned error.
I briefly tried using adodbapi, but I'm getting exactly the same error messages.
The solution ended up being a combination of things.
I needed to disable all IPs other than 127.0.0.1.
I needed to create C:\freetds.conf with the following text:
[global]
port = 1433
tds version = 7.0
I needed to change the account my SQL instance logs in with to LocalSystem.
Yes, 1433 s the default.
This works fine for me:
library(RODBC)
dbconnection <- odbcDriverConnect("Driver=ODBC Driver 11 for SQL Server;Server=server_name; Database=db_name;Uid=; Pwd=; trusted_connection=yes")
initdata <- sqlQuery(dbconnection,paste("select * from MyTable;"))
odbcClose(channel)
Try connecting on the default SQL server port, which is 1433, not 5000.
And check that you can connect to the correct instance using SQL mgmt studio.
I had a similar issue, with the following error:
_mssql.MSSQLDatabaseException: (18456, b"Login failed for user
'script_svc'.DB-Lib error message 20018, severity 14:\nGeneral SQL Server
error: Check messages from the SQL Server\nDB-Lib error message 20002,
severity 9:\nAdaptive Server connection failed\n")
The user I had established was a local user on the machine.
The solution for me was putting ".\" in front of the username and it then recognized it as a local user and allowed the query to work.
Your results may vary.. but I thought I would mention it.
Have you tried using pyodbc instead?
import pyodbc
cnxn = pyodbc.connect('DRIVER={ODBC Driver 13 for SQL Server};SERVER=SERVERNAME;DATABASE=testdb;UID=me;PWD=pass')
cursor = cnxn.cursor()
cursor.execute("select user_id, user_name from users")
rows = cursor.fetchall()
for row in rows:
print row.user_id, row.user_name
Don't forget to add the ODBC driver to your Windows. Go to: Control Panel > Systems and Security > Administrative Tools > ODBC Data Sources
Either the 32-bit or 64-bit version depending on your computer.
Then you click on the System DNS file. If you do not see any MySQL driver you have to click ADD. It brings up a list, from that list select the MySQL driver.
For me, it was ODBC Driver 13 for SQL Server. Click finish. Once you do that then you have to change your connection line in your code to the corresponding Driver that you just filled out.
Source: pyodbc + MySQL + Windows: Data source name not found and no default driver specified
Below is the traceback. I've read all the other SO threads, googled for over two hours, and cannot figure this out. Here is what I have tried:
Both SQL Authentication and Windows Authentication versions of the connection string.
Using the SQL Server name (text) and also the IP Address of the server
Including and Excluding port 1443 (the default tcp/ip port for the SQL server)
Creating new rules in Windows Firewall to allow both inbound/outbound TCP at port 1443
List item
Traceback (most recent call last):
File "pythonscript.py", line 75, in
conn = pyodbc.connect(driver='{SQL Server}', server='ipaddress,1443', database='master', uid='XYZ\login', pwd='password')
pyodbc.Error: ('08001', '[08001] [Microsoft][ODBC SQL Server Driver][DBNETLIB]SQL Server does not exist or access denied. (17) (SQLDriverConnect); [01000] [Microsoft][ODBC SQL Server Driver][DBNETLIB]ConnectionOpen (Connect()). (53)'
here are some examples of what I've tried for the connection string:
conn = pyodbc.connect('Trusted_Connection=yes', driver = '{SQL Server}',server = '1.1.1.1,1443', database = 'master')
then
conn = pyodbc.connect(driver='{SQL Server}', server='1.1.1.1,1443', database='master', uid='xyz\login', pwd='pwd'
then I also tried both of the above with the name of the server (text) rather than the IP address. I have no idea how to get this to work at this point.
Have you confirmed you have connectivity between the servers? Try telnet -
telnet serverName 1433
If that connects then you can focus on issues with Python or the connection string.
In your connection string change it to use the PORT parameter instead of the ,1433. Something like -
SERVER=1.1.1.1;PORT=1433;
I would also say you might be better off passing the whole string. Here is what I do on Linux using FreeTDS typically -
self.db_connection = pyodbc.connect("DRIVER=FreeTDS;SERVER=1.1.1.1;PORT=1433;DATABASE=myDB;UID=myUser;PWD=myPass;TDS_Version=8.0;")
CONNECTION FROM WINDOWS TO MS SQL SERVER DATABASE:
Here you have an example I use myself to connect to MS SQL database table with a Python script:
import pyodbc
server = 'ip_database_server'
database = 'database_name'
username = 'user_name'
password = 'user_password'
driver = '{SQL Server}' # Driver you need to connect to the database
port = '1433'
cnn = pyodbc.connect('DRIVER='+driver+';PORT=port;SERVER='+server+';PORT=1443;DATABASE='+database+';UID='+username+
';PWD='+password)
cursor = cnn.cursor()
If you are trying to connect from a Windows device to the DB, go to ODBC Data Source Administrator from Windows, and check if you have installed the driver:
Where is the ODBC data source administrator in a Windows machine.
The image is in spanish, but you only have to click on 'Drivers' tab, and check if the driver is there as in the image.
CONNECTION FROM LINUX/UNIX TO MS SQL SERVER DATABASE:
If you are working in Linux/Unix, then you shoud install a ODBC manager like 'FreeTDS' and 'unixODBC'. To configure them, you have some examples in the following links:
Example: Connecting to Microsoft SQL Server from Linux/Unix
Example: Installing and Configuring ODBC
I'm trying to connect to a DB2 database using pyodbc on Mac OS X and I can't seem to get this going. I have had success using FreeTDS to connect to MS SQL Server under similar conditions.
First, I installed db2exc_client_952_MAC_x86_64 from IBM. After successfully installing that, I went to add the driver via ODBC Administrator.
Then I've tried running this python:
import pyodbc
cnxn = pyodbc.connect('Driver={IBM DB2 ODBC Driver}; Hostname=myhost.com; Port=50300; Protocol=TCPIP; Database=DB2ET; CurrentSchema=SCHM1; UID=MYUID; PWD=MYPWD;');
And I receive this error:
Traceback (most recent call last):
File "", line 1, in
pyodbc.Error: ('HY000', '[] \xf8\x92\x90\x81\x9b\xf8\x93\x90\x81\x82\xf8\x96\xb0\x81\x9d\xf8\x93\x80\x81\x83\xf8\x88\x80\x81\x89\xf8\x9c\xa0\x81\x84\xf8\x9d\xa0\x81\xa9\xf8\x9c\xa0\x81\xa5\xf8\x88\x80\x81\x9d\xf8\x94\x90\x81\x93\xf8\x8c\x90\x81\x8c\xf8\x8c\xa0\x80\xb0\xf8\x93\xa0\x80\xb4\xf8\x88\x80\x80\xa0\xf8\x88\x80\x81\x81\xf8\x98\x90\x81\xa4\xf8\x98\x90\x81\xb4\xf8\x98\x90\x81\xa2\xf8\x99\x90\x81\xb3\xf8\x98\xb0\x80\xa0\xf8\x9b\xa0\x81\xaf\xf8\x99\x90\x81\xae\xf8\x9d\x80\x81\xa3\xf8\x9b\xb0\x81\xa9\xf8\x88\x80\x81\xae\xf8\x9b\xb0\x81\xa4\xf8\x9c\xb0\x81\xa5\xf8\x9b\xa0\x80\xa0\xf8\x9d\x80\x81\xaf\xf8\x99\x90\x80\xa0\xf8\x9a\x90\x81\xb8\xf8\x9d\x80\x81\xb3\xf8\x88\x80\x80\xae\xf8\x94\xb0\x80\xa0\xf8\x93\x80\x81\x91\xf8\x95\x80\x81\x93\xf8\x95\x80\x81\x81\xf8\x8f\x90\x81\x85\xf8\x8e\x80\x80\xb0\xf8\x8c\x80\x80\xb0\xf2\xa0\x80\xb3\xfc\xa0\x9c\xb0\x80\x80\xfd\xa1\x99\x82\x81\xa1\xfd\xa1\x98\xa6\x85\xb4\xfd\xa9\x88\x86\x95\xb3\xfd\x82\x91\x82\x81\xae\xfd\xaf\x99\xa2\x80\xb2\xfd\x96\x93\x92\x81\xb2\xfd\x93\x82\xa2\xb9\x93\xff\x7f (-1024) (SQLDriverConnect)')
I gathered from searching that HY000 may be a connectionString problem, but I'm not sure how to decipher the rest of the error.
Any ideas?
It appears connection strings vary by database and the connection string you are using is not compatible with DB2.
Here's some DB2 example connection strings:
http://www.connectionstrings.com/ibm-db2
Here's the best reference I could find as to what is valid in a DB2 connection string:
http://publib.boulder.ibm.com/infocenter/db2luw/v9r5/index.jsp?topic=%2Fcom.ibm.swg.im.dbclient.adonet.ref.doc%2Fdoc%2FDB2ConnectionClass.html
Based on that, I'd convert your connection string from:
Driver={IBM DB2 ODBC Driver}; Hostname=myhost.com; Port=50300; Protocol=TCPIP; Database=DB2ET; CurrentSchema=SCHM1; UID=MYUID; PWD=MYPWD;
To:
Driver={IBM DB2 ODBC Driver}; Server=myhost.com:50300; Database=DB2ET; CurrentSchema=SCHM1; UID=MYUID; PWD=MYPWD;
Here's what my connection string looks like in PHP (I know you're using Python but I think they're very similar):
$this->db_connection = new PDO("odbc:DRIVER={iSeries Access ODBC Driver};SYSTEM=10.xxx.xxx.xxx;PROTOCOL=TCPIP", $temp_username, $temp_password);
Notice that I say "SYSTEM=..." and you say "Hostname=..." - I think that could be important.
Is your DSN set up completely? On my Linux machines I have two files that contain all of our configuration information for DSN's.
odbc.ini
[primary]
Description = primary
Driver = iSeries Access ODBC Driver
System = xxx.xxx.xxx.xxx
UserID = xxxxxxxxxx
Password = xxxxxxxxxx
Naming = 0
DefaultLibraries = QGPL
Database = xxxxxxxxxx
ConnectionType = 0
CommitMode = 2
ExtendedDynamic = 0
DefaultPkgLibrary = QGPL
DefaultPackage = A/DEFAULT(IBM),2,0,1,0,512
AllowDataCompression = 1
LibraryView = 0
AllowUnsupportedChar = 0
ForceTranslation = 0
Trace = 0
and odbcinst.ini
[iSeries Access ODBC Driver]
Description = iSeries Access for Linux ODBC Driver
Driver = /usr/lib/libcwbodbc.so
Setup = /usr/lib/libcwbodbcs.so
NOTE1 = If using unixODBC 2.2.11 or later and you want the 32 and 64-bit ODBC drivers to share DSN's,
NOTE2 = the following Driver64/Setup64 keywords will provide that support.
Driver64 = /usr/lib/lib64/libcwbodbc.so
Setup64 = /usr/lib/lib64/libcwbodbcs.so
Threading = 2
DontDLClose = 1
UsageCount = 1
I believe you enter similar information in the dialog you show, probably under the DSN tab.
Have you enabled ODBC tracing? To do this in Linux I have to add this to the odbcinst.ini file:
[ODBC]
Trace = Yes
TraceFile = /tmp/odbc.log
This dumped a LOT of information for me and helped to diagnose some problems I've had in the past.
According to this page (http://code.google.com/p/pyodbc/wiki/ConnectionStrings), "The most important thing to know is that pyodbc does not even look at the connection string -- it is passed directly to SQLDriverConnect unmodified." If that's true then changing your "Hostname" to "SYSTEM" should do the trick.
EDIT
Any chance this could be a problem with encoding? Unicode trying to talk to a UTF-8 server (or something similar)? Have you tried setting the CCSID? When you configure the driver do you have options such as "BinAsChar", "CCSID" or "Host CCSID"?
By default I believe the CCSID is 37 (US/Canada) and I think Unicode is 1208.
Why not define a User DSN using a driver and then use the DSN in the connect() method?
pyodbc.connect( 'DSN=MYDSN;UID=MYUSER;PWD=MYPASS' )
And by the way using any driver other than the "iSeries Access ODBC Driver" might raise those DB2 licensing errors. Maybe this is what the message is saying.
The driver is installed when you install "IBM i Access for Windows 7.1"
There doesn't seem to be any great instructions for setting this up. Does anyone have any good instructions? I am a linux noob so be gentle. I did see another post that is similar, but no real answer.
I have a couple of problems.
FreeTDS doesn't "seem" to be working. I am trying to connect and I get the following message using the "tsql" command: "Default database being set to databaseName
There was a problem connecting to the server" but it doesn't mention what the problem is.
The error I get when I try to connect using pyodbc is: "pyodbc.Error: ('08S01', '[08S01] [unixODBC][FreeTDS][SQL Server]Unable to connect: Adaptive Server is unavailable or does not exist (20009) (SQLDriverConnectW)')"
I tried something similar with pymssql, but I ran into similar issues. I keep getting errors that I can't connect, but it doesn't tell me why.
The following works if you configure the MS SQL server to allow remote TCP/IP connections and have an appropriate user to connect as.
You also need to be careful to set up the correct hostname for the db as reported by MS SQL.
import pymssql
connection = pymssql.connect(
user = 'username',
password = 'password',
host = 'server',
database = 'database',
)
cursor = connection.cursor()
cursor.execute('select * from db;')
rows = cursor.fetchall()
When building FreeTDS (http://www.freetds.org/userguide/config.htm):
./configure --with-tdsver=8.0 --enable-msdblib
That error suggests that the TDS version is not set right. You can set that in the configuration setting for FreeTDS. You don't mention which MSSQL version you are using. But, if you are using say 2005, setting 8.0 as the TDS version will work.