Why is the SQL server DB engine not connecting with SQLAlchemy engine? - python

I am trying to connect to the SQL server database on python platform using SqlAlchemy. I am using windows authentication to connect to my the SQL server. On connecting the server the SqlAlchemy engine is throwing an error:
Below is the code I have implemented:
import os
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
import pyodbc
Driver Server Name Instance Database
DATABASE_URL='mssql+pyodbc://DESKTOP-N32LSOV\PRANAV/AdventureworksDW2016CTP3?trusted_connection=yes'
Engine = create_engine(DATABASE_URL)
cn = Engine.connect()
When the above code is run, this error is produced:
Error:sqlalchemy.exc.InterfaceError: (pyodbc.InterfaceError) ('IM002', '[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)') (Background on this error at: http://sqlalche.me/e/rvf5)
I tried using pymssql driver inplace of pyodbc driver but still the error persists. On contrary when i try to connect to the using the below syntax it connects. I guess i am missing some attribute in the mssql url.
pyodbc.connect(r'Driver={SQL Server};Server=DESKTOP-N32LSOV\PRANAV;Database=master;Trusted_Connection=yes;')
Any help will be appreciated.

You need to specify both that you want to use ODBC and what ODBC driver to use.
engine = sqlalchemy.create_engine('mssql+pyodbc://localhost/Sandbox?driver=SQL+Server+Native+Client+11.0')
If you add the driver= part to your database url, it should work.

If all else fails, I would try using the creator argument to create_engine (documentation):
def creator():
return pyodbc.connect(r'Driver={SQL Server};Server=DESKTOP-N32LSOV\PRANAV;Database=master;Trusted_Connection=yes;')
Engine = create_engine('mssql://', creator=creator)
Using creator= bypasses all connection parameters specified in the URL, so you should only pass information to specify the DB dialect in the URL.
Looking at the mssql+pyodbc dialect/driver documentation, there is also the ?odbc_connect option:
import urllib.parse
CONNECTION_STRING = r'Driver={SQL Server};Server=DESKTOP-N32LSOV\PRANAV;Database=master;Trusted_Connection=yes;'
Engine = create_engine('mssql+pyodbc:///?odbc_connect=' + urllib.parse.quote_plus(CONNECTION_STRING))

Related

Connect to mssql from python

I am trying to connect mssql from python. For this I am using below code but looks like something is wrong with the connection. Can anyone help me ?
import sqlalchemy as sal
from sqlalchemy import create_engine
import pyodbc
##conn = pyodbc.connect('Driver={SQL Server Native client 11.0};server=localhost;database=Nifty;trusted_connection=yes;')
engine = sal.create_engine('mssql+pyodbc://localhost/Nifty?driver=SQL+Server+Native+client+11.0?Trusted_Connection=yes')
engine.execute('select top 2 * from [dbo].ABC')
I am getting below error
InterfaceError: (pyodbc.InterfaceError) ('IM002', '[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)')
(Background on this error at: https://sqlalche.me/e/14/rvf5)
pls first check if you have specified driver in connection:
control panel>Systems and Security>Administrative Tools.>ODBC Data Sources>System DSN tab>Add
and then try :
engine = sal.create_engine('mssql+pyodbc://localhost/Nifty?driver=SQL+Server+Native+client+11.0?Trusted_Connection=yes',echo = True)
official docs
or, You can use some of the Solutions below:
Solution 1
define driver like this :
Driver={ODBC Driver 17 for SQL Server};Server=serverName\instanceName;Database=myDataBase;Trusted_Connection=yes;
and then put it in pyodbc.connect(" here ") and run it using cursor, see this
Solution 2
With Windows Authentication Without using DSN's
engine = sal.create_engine('mssql+pyodbc://server/db')
Solution 3
using urllib
import urllib
params = urllib.parse.quote_plus("DRIVER={SQL Server Native Client 11.0};"
"SERVER=dagger;"
"DATABASE=test;"
"Trusted_Connection=yes")
engine = sa.create_engine("mssql+pyodbc:///?odbc_connect={}".format(params))

Connect to SQLite3 with pyodbc for fast_executemany

We currently use a program that creates and writes large datasets to databases, but the process can take a long time. We are trying to incorporate cursor.fast_executemany = True from sqlalchemy to improve the write times to these databases. My code errors out when I try to create an engine using SQLite3 and pyodbc here:
import pandas as pd
from sqlite3 import connect
import pyodbc
from sqlalchemy import create_engine
engine = create_engine('SQLite3 ODBC Driver+pyodbc:///C:\\Users\\Documents\\PythonScripts\\FLR.sosat')
conn = engine.connect()
c = conn.cursor()
We have tried numerous ways where we specify the driver and server and things like that like the following:
# conn = pyodbc.connect('DRIVER={SQL Server};'
# 'SERVER=localhost;'
# 'DATABASE=C:\\Users\\Documents\\PythonScripts\\FLR.sosat')
The single engine line seems to be the closest to working due to us receiving driver and server errors from the commented out code above. We have downloaded the ODBC driver from http://www.ch-werner.de/sqliteodbc/
We receive the ArgumentError: Could not parse rfc1738 URL from string.
We would appreciate any help or ideas on how to get the SQLite3 database to pyodbc and how to improve the write speed. Thanks!
Note the .sosat file is a database file that uses sqlite3, it should work like any .db file
We tried the fix from here: Connect to SQLite3 server using PyODBC, Python and that did not work for us, we received the driver error:
InterfaceError: ('IM002', '[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)')
What you are trying to accomplish will not work for two reasons:
Reason 1:
SQLAlchemy does not support pyodbc as a DBAPI layer for SQLite.
Reason 2:
Even if SQLAlchemy did support sqlite+pyodbc:// the SQLite ODBC Driver would have to support "parameter arrays", an optional ODBC feature that fast_executemany = True uses to do its magic. Not all ODBC drivers support fast_executemany = True as shown here. A quick test with vanilla pyodbc shows that "SQLite3 ODBC Driver" doesn't support it, in fact it crashes the Python interpreter:
crsr.fast_executemany = True
crsr.executemany(
f"INSERT INTO {table_name} (txt) VALUES (?)", [("foo",), ("bar",)]
)
# Process finished with exit code -1073741819 (0xC0000005)
(Error 0xC0000005 is "Access Violation".)
Have you tried
import sqlite3
db = r'C:\Users\Documents\PythonScripts\FLR.sosat'
conn = sqlite3.connect(db)
print('connection established')

Pandas sqlalchemy create_engine connection with SQL server windows authentication

I am trying to upload a Pandas DataFrame to SQL server table. From reading, the sqlalchemy to_sql method seems like a great option. However, I am not able to get the create_engine to make the connection.
I am able to connect to the database to retrieve data with Windows authentication. Here is the connection string I am using:
cnxn = pyodbc.connect("Driver={SQL Server Native Client 11.0};"
"Server={server_name};"
"Database={database_name};"
"Trusted_Connection=yes;")
I have tried several different ways to use my login information to connect, here is the most recent version:
engine = create_engine(
"mssql+pyodbc://{network_user_name}:{network_pw}#{server_name}//{database_name}"
)
engine.connect()
Here is the error I am getting:
InterfaceError: (pyodbc.InterfaceError) ('IM002', '[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)')
(Background on this error at: http://sqlalche.me/e/rvf5)
If you are going to use Windows authentication then you simply omit the username/password part of the connection URI. This works fine for me:
connection_uri = (
"mssql+pyodbc://#192.168.0.179:49242/mydb?driver=ODBC+Driver+17+for+SQL+Server"
)
engine = sa.create_engine(connection_uri)

pyodbc autocommit does not appear to work with sybase and sqlalchemy

I am connecting to a sybase ASE 15 database from Python 3.4 using pyodbc and executing a stored procedure.
All works as expected if I use native pyodbc:
import pd
import pyodbc
con = pyodbc.connect('DSN=dsn_name;UID=username;PWD=password', autocommit=True)
df = pd.read_sql("exec p_procecure #GroupName='GROUP'", con)
[Driver is Adaptive Server Enterprise].
I have to have autocommit=True and if I do no I get the following error:
DatabaseError: Execution failed on sql 'exec ....': ('ZZZZZ', "[ZZZZZ]
[SAP][ASE ODBC Driver][Adaptive Server Enterprise]Stored procedure
'p_procedure' may be run only in unchained transaction mode. The 'SET
CHAINED OFF' command will cause the current session to use unchained
transaction mode.\n (7713) (SQLExecDirectW)")
I attempt to achieve the same using SQLAlchemy (1.0.9):
from sqlalchemy import create_engine, engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql import text
url = r'sybase+pyodbc://username:password#dsn'
engine = create_engine(url, echo=True)
sess = sessionmaker(bind=engine).Session()
df = pd.read_sql(text("exec p_procedure #GroupName='GROUP'"),conn.execution_options(autocommit=True))
The error message is the same despite the fact I have specified autocommit=True on the connection. (I have also tested this at the session level but should not be necessary and made no difference).
DBAPIError: (pyodbc.Error) ('ZZZZZ', "[ZZZZZ] [SAP][ASE ODBC
Driver][Adaptive Server Enterprise]....
Can you see anything wrong here?
As always, any help would be much appreciated.
Passing the autocommit=True argument as an item in the connect_args argument dictionary does work:
connect_args = {'autocommit': True}
create_engine(url, connect_args=connect_args)
connect_args – a dictionary of options which will be passed directly
to the DBAPI’s connect() method as additional keyword arguments.
I had some problems with autocommit option. The only thing that worked for me was to change this option to True after establishing connection.
ConnString = 'Driver=%SQL_DRIVER%;Server=%SQL_SERVER%;Uid=%SQL_LOGIN%;Pwd=%SQL_PASSWORD%;'
SQL_CONNECTION = pyodbc.connect(ConnString)
SQL_CONNECTION.autocommit = True

How do I connect to SQL Server via sqlalchemy using Windows Authentication?

sqlalchemy, a db connection module for Python, uses SQL Authentication (database-defined user accounts) by default. If you want to use your Windows (domain or local) credentials to authenticate to the SQL Server, the connection string must be changed.
By default, as defined by sqlalchemy, the connection string to connect to the SQL Server is as follows:
sqlalchemy.create_engine('mssql://*username*:*password*#*server_name*/*database_name*')
This, if used using your Windows credentials, would throw an error similar to this:
sqlalchemy.exc.DBAPIError: (Error) ('28000', "[28000] [Microsoft][ODBC SQL Server Driver][SQL Server]Login failed for us
er '***S\\username'. (18456) (SQLDriverConnect); [28000] [Microsoft][ODBC SQL Server Driver][SQL Server]Login failed for us
er '***S\\username'. (18456)") None None
In this error message, the code 18456 identifies the error message thrown by the SQL Server itself. This error signifies that the credentials are incorrect.
In order to use Windows Authentication with sqlalchemy and mssql, the following connection string is required:
ODBC Driver:
engine = sqlalchemy.create_engine('mssql://*server_name*/*database_name*?trusted_connection=yes')
SQL Express Instance:
engine = sqlalchemy.create_engine('mssql://*server_name*\\SQLEXPRESS/*database_name*?trusted_connection=yes')
If you're using a trusted connection/AD and not using username/password, or otherwise see the following:
SAWarning: No driver name specified; this is expected by PyODBC when using >DSN-less connections
"No driver name specified; "
Then this method should work:
from sqlalchemy import create_engine
server = <your_server_name>
database = <your_database_name>
engine = create_engine('mssql+pyodbc://' + server + '/' + database + '?trusted_connection=yes&driver=ODBC+Driver+13+for+SQL+Server')
A more recent response if you want to connect to the MSSQL DB from a different user than the one you're logged with on Windows. It works as well if you are connecting from a Linux machine with FreeTDS installed.
The following worked for me from both Windows 10 and Ubuntu 18.04 using Python 3.6 & 3.7:
import getpass
from sqlalchemy import create_engine
password = getpass.getpass()
eng_str = fr'mssql+pymssql://{domain}\{username}:{password}#{hostip}/{db}'
engine = create_engine(eng_str)
What changed was to add the Windows domain before \username.
You'll need to install the pymssql package.
Create Your SqlAlchemy Connection URL      From Your pyodbc Connection String      OR Your Known Connection Parameters
I found all the other answers to be educational, and I found the SqlAlchemy Docs on connection strings helpful too, but I kept failing to connect to MS SQL Server Express 19 where I was using no username or password and trusted_connection='yes' (just doing development at this point).
Then I found THIS method in the SqlAlchemy Docs on Connection URLs built from a pyodbc connection string (or just a connection string), which is also built from known connection parameters (i.e. this can simply be thought of as a connection string that is not necessarily used in pyodbc). Since I knew my pyodbc connection string was working, this seemed like it would work for me, and it did!
This method takes the guesswork out of creating the correct format for what you feed to the SqlAlchemy create_engine method. If you know your connection parameters, you put those into a simple string per the documentation exemplified by the code below, and the create method in the URL class of the sqlalchemy.engine module does the correct formatting for you.
The example code below runs as is and assumes a database named master and an existing table named table_one with the schema shown below. Also, I am using pandas to import my table data. Otherwise, we'd want to use a context manager to manage connecting to the database and then closing the connection like HERE in the SqlAlchemy docs.
import pandas as pd
import sqlalchemy
from sqlalchemy.engine import URL
# table_one dictionary:
table_one = {'name': 'table_one',
'columns': ['ident int IDENTITY(1,1) PRIMARY KEY',
'value_1 int NOT NULL',
'value_2 int NOT NULL']}
# pyodbc stuff for MS SQL Server Express
driver='{SQL Server}'
server='localhost\SQLEXPRESS'
database='master'
trusted_connection='yes'
# pyodbc connection string
connection_string = f'DRIVER={driver};SERVER={server};'
connection_string += f'DATABASE={database};'
connection_string += f'TRUSTED_CONNECTION={trusted_connection}'
# create sqlalchemy engine connection URL
connection_url = URL.create(
"mssql+pyodbc", query={"odbc_connect": connection_string})
""" more code not shown that uses pyodbc without sqlalchemy """
engine = sqlalchemy.create_engine(connection_url)
d = {'value_1': [1, 2], 'value_2': [3, 4]}
df = pd.DataFrame(data=d)
df.to_sql('table_one', engine, if_exists="append", index=False)
Update
Let's say you've installed SQL Server Express on your linux machine. You can use the following commands to make sure you're using the correct strings for the following:
For the driver: odbcinst -q -d
For the server: sqlcmd -S localhost -U <username> -P <password> -Q 'select ##SERVERNAME'
pyodbc
I think that you need to put:
"+pyodbc" after mssql
try this:
from sqlalchemy import create_engine
engine = create_engine("mssql+pyodbc://user:password#host:port/databasename?driver=ODBC+Driver+17+for+SQL+Server")
cnxn = engine.connect()
It works for me
Luck!
If you are attempting to connect:
DNS-less
Windows Authentication for a server not locally hosted.
Without using ODBC connections.
Try the following:
import sqlalchemy
engine = sqlalchemy.create_engine('mssql+pyodbc://' + server + '/' + database + '?trusted_connection=yes&driver=SQL+Server')
This avoids using ODBC connections and thus avoids pyobdc interface errors from DPAPI2 vs DBAPI3 conflicts.
I would recommend using the URL creation tool instead of creating the url from scratch.
connection_url = sqlalchemy.engine.URL.create("mssql+pyodbc",database=databasename, host=servername, query = {'driver':'SQL Server'})
engine = sqlalchemy.create_engine(connection_url)
See this link for creating a connection string with SQL Server Authentication (non-domain, uses username and password)

Categories

Resources