This works:
db = pyodbc.connect('driver={SQL Server Native Client 11.0}; server=172.30.0.194; database=db;uid=someuser; pwd=fancy#password')
This doesn't
cn_string = "mssql+pyodbc://someuser:"fancy&password"#172.30.0.194/db?driver=SQL+Server+Native+Client+11.0"
return create_engine(cn_string)
This doesn't either:
driver = "SQL Server Native Client 11.0"
server = "192.30.0.194"
database = "EPM_Dashboard"
uid = "someuser"
pwd = "fancy#password"
params = f'DRIVER={{{driver}}};SERVER={server};DATABASE={database};UID={uid};PWD={{{pwd}}};'
connection_string = 'mssql+pyodbc:///?odbc_connect=%s' % urllib.parse.quote_plus(params)
return create_engine(connection_string)
I get something like:
Login timeout expired (0); [08001] [Microsoft][SQL Server Native Client 11.0]A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online. (53)
which would be more believable if the pyodbc item failed.
Here's another failure:
return create_engine(urllib.parse.quote_plus('driver={SQL Server Native Client 11.0}; server=172.30.0.194; database=EPM_Dashboard;uid=someuser; pwd=fancy#password'))
I'm sure there's a tricky character somewhere I'm missing.
Here are some resources
https://github.com/mkleehammer/pyodbc/wiki/Connecting-to-databases
Special character in SQL password
SqlAlchemy equivalent of pyodbc connect string using FreeTDS
If you need to construct a connection URI that may have "funny characters" in it then you can use engine.URL.create() to build it for you:
import sqlalchemy as sa
connection_uri = sa.engine.URL.create(
"mssql+pyodbc",
username="someuser",
password="fancy#password",
host="192.30.0.194",
database="EPM_Dashboard",
query={"driver": "SQL Server Native Client 11.0"},
)
print(connection_uri)
# mssql+pyodbc://someuser:fancy%40password#192.30.0.194/EPM_Dashboard?driver=SQL+Server+Native+Client+11.0
Related
I am trying to access tables in SQL database in Azure Managed Instance (with IP: xxxx.database.windows.net) from a python script in Azure VM machine but I am getting the Operational Error below. I have tried with 2 different ways below.
Error:
OperationalError: ('08001', '[08001] [Microsoft][SQL Server Native Client 11.0]TCP Provider: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.\r\n (10060) (SQLDriverConnect); [08001] [Microsoft][SQL Server Native Client 11.0]Login timeout expired (0); [08001] [Microsoft][SQL Server Native Client 11.0]A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online. (10060)')
1st way with connectionString:
import pandas as pd
from sqlalchemy import create_engine
engine = create_engine("mssql+pyodbc://<username>:<password>#<server>/<database>?driver=SQL+Server+Native+Client+11.0")
query = "select * from table"
df=pd.read_sql(query,engine)
2nd way with connectionString:
import pyodbc
server = 'xxx.database.windows.net'
database = 'database'
username = 'username'
password = 'password'
driver= '{SQL Server Native Client 11.0}'
with pyodbc.connect('DRIVER='+driver+';SERVER='+server+';PORT=1433;DATABASE='+database+';UID='+username+';PWD='+ password) as conn:
with conn.cursor() as cursor:
cursor.execute("SELECT TOP 3 name, collation_name FROM sys.databases")
row = cursor.fetchone()
while row:
print (str(row[0]) + " " + str(row[1]))
row = cursor.fetchone()
Besides, I have also tried to change the driver to drivers below, still no luck.
{ODBC Driver 11 for SQL Server}
{ODBC Driver 13 for SQL Server}
{ODBC Driver 17 for SQL Server}
{SQL Server Native Client 11.0}
Interesting part is, if I try the connect with the same connection string from on-premise machine which is not Azure VM (ex: my local machine or other servers I can RDP to), I can access the database. But when I try on a Azure VM machine, it is timing out. Do you have any ideas how to fix this problem?
Thank you for inputs.
So in the end we foud out that firewall caused this problem. We need to check firewall rules first.
Recent hardening standards have made us disable TLS 1.0 and 1.1.
Registry Settings for TLS 1.0 and 1.1:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client
Now the following code:
from sqlalchemy import create_engine
db = create_engine(
"mssql+pyodbc://__OUR_SERVER_NAME__/__OUR_DATABSE_NAME__?driver=SQL+Server+Native+Client+11.0&Trusted_Connection=yes&Encrypt=yes&TrustServerCertificate=Yes&ssl=True",
connect_args={
# 'sslmode': 'require', # did not work
# 'tls-version': 'tls1.2', # did not work
# 'ssl': True, # did not work
},
echo=True,
)
with db.begin() as conn:
conn.execute("SELECT TOP 5 * FROM sys.tables")
Will throw this exception on db.begin():
Exception has occurred: OperationalError
(pyodbc.OperationalError) ('08001', '[08001] [Microsoft][SQL Server Native Client 11.0]Encryption not supported on the client. (21) (SQLDriverConnect); [08001] [Microsoft][SQL Server Native Client 11.0]SSL Provider: The client and server cannot communicate, because they do not possess a common algorithm.\r\n (-2146893007); [08001] [Microsoft][SQL Server Native Client 11.0]Client unable to establish connection (21); [08001] [Microsoft][SQL Server Native Client 11.0]Invalid connection string attribute (0); [08001] [Microsoft][SQL Server Native Client 11.0]A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online. (-2146893007)')
TLS 1.2 is enabled and works fine with Azure Data Studio on the same client server.
Even python shows openssl version is resonable:
import ssl
print(f'SSL Version = {ssl.OPENSSL_VERSION}')
which outputs:
SSL Version = OpenSSL 1.1.1d 10 Sep 2019
Python version:
python --version
Python 3.7.6
I have tried looking at SSLContext but can't seem to find how to make it work with SqlAlchemy.
Any help would be greatly appreciated!!!
Possible duplicate question (with less info): Connecting to SQL Server using pyodc with TLS 1.2
Further investigation showed an issue with the ODBC driver.
The app was on Windows Server 2012 with ODBC version:
SQL Server Native Client 11.0
Version: 2011.110.3000.00
Date: 10/20/2012
Updating the driver to ODBC Driver 17 for SQL Server with new connection string worked:
from sqlalchemy import create_engine
db = create_engine(
"mssql+pyodbc://__OUR_SERVER_NAME__/__OUR_DATABSE_NAME__?driver=ODBC+Driver+17+for+SQL+Server&Trusted_Connection=yes&Encrypt=yes&TrustServerCertificate=Yes&ssl=True",
connect_args={
# 'sslmode': 'require', # did not work
# 'tls-version': 'tls1.2', # did not work
# 'ssl': True, # did not work
},
echo=True,
)
I ran into this issue where I couldn't connect to SQL server using the credentials .
I can connect when using trusted connection = yes .
Am I doing something wrong here ? Should something be added or concidered ?
conn = pyodbc.connect('Driver={SQL Server Native Client 11.0};'
'Server=1070010-01;'
'Database=test_DB;'
'Uid =sa;'
'Pwd =SDTK-1111;'
)
I have also tried replacing Uid and Pwd with username and password .
I have also tried adding trusted_connection = no
In all the above cases , I get this error :
conn = pyodbc.connect('Driver={SQL Server Native Client 11.0};'
pyodbc.InterfaceError: ('28000', "[28000] [Microsoft][SQL Server Native Client 11.0][SQL Server]Login failed for user ''. (18456) (SQLDriverConnect); [28000] [Microsoft][SQL Server Native Client 11.0]Invalid connection string attribute (0); [28000] [Microsoft][SQL Server Native Client 11.0][SQL Server]Login failed for user ''. (18456); [28000] [Microsoft][SQL Server Native Client 11.0]Invalid connection string attribute (0)")
try this , string was not well formatted
conn = pyodbc.connect('Driver={SQL Server Native Client 11.0}; Server=1070010-01; uid=sa; pwd=SDTK-1111; Database = test_DB; Trusted_Connection=No;')
So I am trying to write a data frame to Microsoft SQL Server using the pandas to_sql function.
I have created an engine using
engine = sqlalchemy.create_engine(
'mssql:///Server/Database?driver=SQL Server Native Client 11.0'
)
con = engine.connect()
switchers.to_sql('check',engine)
The error I am getting is as follows :
OperationalError: (pyodbc.OperationalError) ('08001', '[08001] [Microsoft][SQL Server Native Client 11.0]Named Pipes Provider: Could not open a connection to SQL Server [2]. (2) (SQLDriverConnect); [08001] [Microsoft][SQL Server Native Client 11.0]Login timeout expired (0); [08001] [Microsoft][SQL Server Native Client 11.0]A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online. (2)') (Background on this error at: http://sqlalche.me/e/e3q8)
Any idea what I should be looking for?
Your connection string should be:
engine =
sqlalchemy.create_engine('mssql+pyodbc://Server/Database?driver=SQL+Server+Native+Client+11.0')
I used the pyodbc and pypyodbc python package to connect to SQL server.
Drivers used anyone of these ['SQL Server', 'SQL Server Native Client 10.0', 'ODBC Driver 11 for SQL Server', 'ODBC Driver 13 for SQL Server'].
connection string :
connection = pyodbc.connect('DRIVER={SQL Server};'
'Server=aaa.database.windows.net;'
'DATABASE=DB_NAME;'
'UID=User_name;'
'PWD=password')
now I am getting error message like
DatabaseError: (u'28000', u"[28000] [Microsoft][ODBC SQL Server Driver][SQL Server]Login failed for user
But I can connect to the server through the SQL server management studio.
its on SQL Server Authentication, Not Windows Authentication.
Is this about python package and driver issue or DB issue??? how to solve?
You can add Trusted_Connection=NO; in your connection string after the password
I see you have no port defined in your script.
The general way to connect to a server using pyodbc ${DBName} ${DBUser} ${DBPass} ${DBHost} ${DBPort}, where DBName is your database name, DBUser is the username used to connect to it, DBPass is the password, DBHost is the URL of your database, and DBPort is the port you use to connect to your DB.
I use MS SQL so my port is 1433, yours might be different.
I've had this issue just today, and that fixed it.
The problem is not driver issue, you can see the error message is DatabaseError: Login failed for user, it means this problem occurs if the user tries to log in with credentials that cannot be validated. I suspect you are login with your windows Authentication, if so, use Trusted_Connection=yes instead:
connection = pyodbc.connect('DRIVER={SQL Server};Server=aaa.database.windows.net;DATABASE=DB_NAME;Trusted_Connection=yes')
For more details, please refer to my old answer about the difference of SQL Server Authentication modes.
I think problem because of driver definition in your connection string. You may try with below.
connection = pyodbc.connect('DRIVER={SQL Server Native Client 10.0}; Server=aaa.database.windows.net; DATABASE=DB_NAME; UID=User_name; PWD=password')
I applied your connection string and updated it with my server connections details and it worked fine.
Are you sure your are passing correct user name and password ?
Login failed implies connection was established successfully, but authentication didn't pass.