Connecting to MS-SQL from pyodbc using windows authentication - python

I am trying to connect to MSSQL server using pyodbc. I can connect to the server and query it using the basic authentication mode as:
connection = pyodbc.connect("DRIVER={Easysoft ODBC-SQL Server};SERVER=192.168.2.119;DATABASE=dbame;UID=**;PWD=****")
Connection to MSSQL can also be done using Windows Authentication where it takes the parameters
DOMAIN
USERNAME
PASSWORD
I don't know how to use this sort of credential from pyodbc to connect to the MSSQL Server.
Furthermore, the ODBC driver I am using (Easysoft ODBC-SQL Server) needs licensing. Don't we get such drivers for free?

The Easysoft SQL Server driver parameters to use NTLM authentication are
Trusted_Domain=<domain name>
NTLMv2=Yes|No
Trusted_Connection=Yes|No
And UID, PWD as usual.
NTLM can also be triggered simply using a UID that looks like
DOMAIN\USER
If you want to use Kerberous, the following can be set
ServerSPN=SPN
Its all the the user guide for the driver

connection = pyodbc.connect("DRIVER={Easysoft ODBC-SQL Server};SERVER=192.168.2.119;DATABASE=dbame;UID=;PWD=**")
The string part of the connection is what is known as a DSN-Less connection so you can pass in any of the attributes required for example :-
connection = pyodbc.connect("DRIVER={Easysoft ODBC-SQL Server};SERVER=192.168.2.119;DATABASE=dbame;UID=MyWindowsUserName;PWD=MyPassword;Trusted_Domain=MyWindowsDomainName;Trusted_Connection=1")
Trusted_Connection = 1 tells the Easysoft driver that you intend to use the Trusted_Domain, user ( UID ) and password ( PWD ) to login to SQL Server.
For a full list of all the attributes available within the Easysoft ODBC-SQL Server Driver please read the Attributes section of the manual.

Related

Getting Login Failed error with sqlalchemy+PYODBC when trying to connect to mssql DB server with another Domain credentials,but connected with Pymssql [duplicate]

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

azure function using pyodbc works fine on local machine, but not on azure cloud

I developed a simple python Azure function app using pyodbc to select a few rows from a public IP MS SQL server. My function app runs fine on my laptop, but it doesn't work when I publish it on Azure cloud (I used Consumption - serverless plan, linux environment). Thru the logging, I knows that it always gets stuck at the pyodbc.connect(...) command and time-out.
#...
conn_str = f'Driver={driver};Server={server},{port};Database={database};Uid={user};Pwd={password};Encrypted=yes;TrustServerCertificate=no;Connection Timeout=30'
sql_query = f'SELECT * FROM {table_name}'
try:
conn = pyodbc.connect(conn_str) # always time-out here if running on Azure cloud!!!
logging.info(f'Inventory API - connected to {server}, {port}, {user}.')
except Exception as error:
logging.info(f'Inventory API - connection error: {repr(error)}.')
else:
with conn.cursor() as cursor:
cursor.execute(sql_query)
logging.info(f'Inventory API - executed query: {sql_query}.')
data = []
for row in cursor:
data.append({'Sku' : row.Sku, 'InventoryId' : row.InventoryId, 'LocationId' : row.LocationId, 'AvailableQuantity' : row.AvailableQuantity})
#...
The logging captured:
Inventory API - connection error: OperationalError('HYT00', '[HYT00] [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired (0) (SQLDriverConnect)').
I already include the pyodbc in the requirements.txt file. I also allows all outboundIpAddresses and possibleOutboundIpAddresses of my function app on my SQL server firewall. My function app does not have any network restriction on Azure cloud (or at least it said so on the network settings).
my config file:
driver={ODBC Driver 17 for SQL Server}
server=I tried both IP and full internet host name, both didn't work
Could someone give me a hint? Thanks.
Workarounds to fix the PYODBC connection Error
Try to use a below format
import pyodbc
server = 'tcp:myserver.database.windows.net'
database = 'mydb'
username = 'myusername'
password = 'mypassword'
conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
If you are using Domain Name add TCP with domain name server = 'tcp:myserver.database.windows.net' otherwise use the IP server = '129.0.0.1’
If you are using port use like this 'tcp:myserver.database.windows.net,1233’ or '129.0.0.1,1233'
Try to remove additional properties like Connection_Timeout, Trusted_certificate and all and check now.
Refer here
I put the following snippet into my function to check the outbound IP, and found out that Azure use a few outbound IPs that are not listed in the [outboundIpAddresses] and [possibleOutboundIpAddresses] (documented in this MS link)
import requests
#...
outbound_ip_response = requests.request('GET', 'https://checkip.amazonaws.com')
logging.info(f'Inventory API - main()- outbound ip = {outbound_ip_response.text}')
So, I followed the instructions in this link to setup a static outbound IP for my function app and allowed this IP to access my SQL server. It worked.

Connecting Python with Google SQL

I need to connect the Python script with google sql.
I have created the database in google sql and now want to connect it with python script.
I am trying to use this so far:
conn = pymysql.connect(host='ip.ip.ipi.ip',user='user', passwd = "passwd", db = 'mysql',
charset = 'utf8')
cur = conn.cursor()
cur.execute("USE Example_Database")
but getting this error:
OperationalError: (2003, "Can't connect to MySQL server on '35.246.235.61' (timed out)")
Also tried to use this but not working:
from google.cloud.sql.connector import connector
connector.connect(
"instance:instancename",
"mysql-connector",
host='ip.ip.ipi.ip',
user="user",
password="passwd",
db="Database"
)
It seems there is connectivity issue to Google SQL from where you run the code.
Where are you running your python code?
Can you check if it can connec to you Google SQL endpoint on port 3306 (or custom port you are using)?
telnet <Google_SQL_IP> 3306
Depending on where your python code is hosted you need to allow necessary access for your app server to cloud sql.
You can connect to a Cloud SQL instance using the following methods:
By using the proxy (Second Generation instances only)
By configuring access for one or more public IP addresses
By using the JDBC Socket Factory (for the Java programming language, Second Generation instances only)
By using the Cloud SQL Proxy library (for the Go programming language, Second Generation instances only)
Please review the following link which describes options for you to connect:
https://cloud.google.com/sql/docs/mysql/connect-external-app

Can't connect to SQL Server on AWS RDS via Python

I am trying to connect a python terminal to a SQL Server database on AWS RDS.
I've looked through Microsoft's documentation on how to do it here, and I've seen aplethora of different questions asked here on Stack Overflow, however I think my unique problem is mapping the connection process to specific aspects of the RDS environment, and I'm unsure if my environment is setup correctly, and I can't find a question that maps directly to the issues I'm trying to research.
WHAT I HAVE RIGHT NOW:
import pyodbc as pydb
connection = pydb.connect('DRIVER={SQL Server};PORT=1433;SERVER=aws-database-endpoint;UID=instance-master-username;PWD=instance-password;DATABASE=db-instance-id')
print("Connecting....")
connection.close()
And getting the following traceback:
InterfaceError: ('28000', "[28000] [Microsoft][ODBC SQL Server Driver][SQL Server]Login failed for user 'admin'. (18456) (SQLDriverConnect); [28000] [Microsoft][ODBC SQL Server Driver]Invalid connection string attribute (0); [28000] [Microsoft][ODBC SQL Server Driver][SQL Server]Login failed for user 'admin'. (18456); [28000] [Microsoft][ODBC SQL Server Driver]Invalid connection string attribute (0)")
To provide more detail, here's a picture of what my database setup currently looks like:
For port, and server, I'm getting the info from here:
For UID I'm going to RDS --> Databases, clicking on my instance and then going to Configuration, and I'm entering the Master Username, which is admin, as can be seen here:
And for my DATABASE value, I'm at the same spot, and using the database instance-id, which can be seen here:
I've created a rule that allows my IP address for incoming TCP traffic via VPC resource groups here:
What I've also tried:
using my account ID for the UID argument
using my AWS username for the UID argument
database is publicly accessible
I have tried logging in both as a root user, and as an IAM user with administrator privileges
I can't tell if I'm making a clerical mistake or if there is a larger admin issue that I'm not identifying.
Thank you.
use the sample connection below, note there is not port if its the default 1433
cnxn = pyodbc.connect('DRIVER={/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.3.so.1.1};SERVER='+server+';DATABASE='+database+';uid='+username+';pwd='+ password)
If you are running the python script from your local machine (wsl, linux box or ec2) make sure the msodbc drivers are correctly installed
You can also try this, it was easier than pyodbc for me:
import pymssql
connection={
'host': '',
'username': '',
'password': '',
'db': ''
}
con=pymssql.connect(connection['host'],connection['username'],connection['password'],connection['db'])
cursor=con.cursor()
Running into this problem myself I found that AWS RDS doesn't actually give you an option to name your database within the instance in SQL server like it does with PostreSQL when instantiating or afterwords and rather than giving it the name of the instance it leaves this field blank. You can confirm this by looking at the configuration tab within the instance summary in the AWS dashboard, under DB name there is simply a dash to indicate a blank field. I was able to solve the problem by just removing the database name field from my connection string. So the string the original example would look like this:
import pyodbc as pydb
connection = pydb.connect('DRIVER={SQL Server};PORT=1433;SERVER=aws-database-endpoint;UID=instance-master-username;PWD=instance-password;')
Try to bring each component to a variable
import pyodbc
server = 'tcp:myserver.database.windows.net'
database = 'mydb'
username = 'myusername'
password = 'mypassword'
cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
cursor = cnxn.cursor()
#Sample select query
query = 'SELECT....'
df = pd.sql_read(query, cnxn)
print(df)

Connect to remote MSSQL 2016 using isql and python on Mac?

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!

Categories

Resources