SQLAlchemy df.to_sql MSSQL - python

I am trying to move data from a database I own to a database I only have read/write permissions on (as a temp table). However, I get an error. Please see the below code:
import pandas as pd
import pyodbc
import sqlalchemy
con = pyodbc.connect(r'Driver={SQL Server};Server=MYServer;Database=DB_People;Trusted_Connection=yes;)
sSQL = "SELECT * FROM tbl_People;"
df = pd.read_sql(sSQL, con)
con.close()
con = pyodbc.connect(r'Driver={SQL Server};Server=NOT_MyServer;Database=DB_People;Trusted_Connection=yes;)
sSQL = "CREATE TABLE [##People Table] (p_Name varchar(25), p_DOB char(10));"
con.execute(sSQL)
con.committ()
engine = sqlalchemy.create_engine('mssql://NOT_MyServer/DB_People?Driver=SQL+Server+Native+Client+11.0?trusted_connection=yes')
df.to_sql("##People Table")
I get the error:
DBAPIError: (pyodbc.Error) ('IM002', '[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)')
Any clues as to what the issue is? I specified a Driver in my connection and I know the Temp table exists because when I connect via SSMS I can query the table (although there are no records at this point.
I

It seems as if I have found the problem(s):
The "Create Table" function is unneeded as the df.to_sql creates the table
Instead of the "+" in the Driver name, I was able to replace them with %20
This worked for me.

Related

How do I create a copy of a table using PYODBC?

I'm using 32-bit Python along with 32-bit Microsoft Access.
I connect to the database and create a cursor.
conn = pyodbc.connect(r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=P:\path\database.accdb;')
c = conn.cursor()
I then read in a table for future use:
c.execute('select * from tbl')
tbl = c.fetchall()
But when I try to make a copy of the table using:
query = 'CREATE TABLE tbl2 LIKE tbl'
c.execute(query)
I get a programming error:
ProgrammingError: ('42000', '[42000] [Microsoft][ODBC Microsoft Access Driver] Syntax error in CREATE TABLE statement. (-3551) (SQLExecDirectW)')
I'm new to PYODBC but this is a pretty basic SQL line. Any tips on what might be wrong?
Due to a lack of documentation, the best way I found to figure this out is to use Microsoft Access to create a template for the query...example below worked.
query = 'SELECT tbl.* INTO tbl2 FROM tbl'
c.execute(query)

exporting pandas dataframe into a access table using to_sql generate error

I am trying to use sqlalchemy-access library to insert a data frame into an access database:
The code that I have is:
import msaccessdb
import pyodbc
import pandas as pd
print(pyodbc.version)
db_file = r'database\sampledatabase.accdb'
input_csv_file= r'database\sample_data.csv'
print(input_csv_file)
msaccessdb.create(db_file)
cnxn_str = (
r'DRIVER={{Microsoft Access Driver (*.mdb, *.accdb)}};'
r'DBQ={};'
r'ExtendedAnsiSQL=1;'.format(db_file)
)
print(cnxn_str)
cnxn = pyodbc.connect(cnxn_str,autocommit=True)
input_data=pd.read_csv(input_csv_file)
input_data.to_sql('sample_table', cnxn, index=False, if_exists='replace')
cnxn.close()
but when I run this code, I am getting this error:
Execution failed on sql 'SELECT name FROM sqlite_master WHERE type='table' AND name=?;': ('42S02', "[42S02] [Microsoft][ODBC Microsoft Access Driver] The Microsoft Access database engine cannot find the input table or query 'sqlite_master'. Make sure it exists and that its name is spelled correctly. (-1305) (SQLExecDirectW)")
the error is generated when I am trying to run this line:
input_data.to_sql('sample_table', cnxn, index=False, if_exists='replace')
what is wrong with this code and how can I fix it?
Edit 1
Based on the comments and this post, I changed the code to this:
import msaccessdb
import pandas as pd
from sqlalchemy import create_engine
import urllib
db_file = r'database\sampledatabase.accdb'
input_csv_file= r'database\sample_data.csv'
msaccessdb.create(db_file)
cnxn_str = (
r'DRIVER={{Microsoft Access Driver (*.mdb, *.accdb)}};'
r'DBQ={};'
r'ExtendedAnsiSQL=1;'.format(db_file)
)
params = urllib.parse.quote_plus(cnxn_str)
engine = create_engine("mssql+pyodbc:///?odbc_connect=%s" % params)
print(cnxn_str)
create_engine("access+pyodbc://#your_dsn")
input_data=pd.read_csv(input_csv_file)
input_data.to_sql('sample_table', engine, index=False, if_exists='replace')
but I am still getting error:
(pyodbc.ProgrammingError) ('42000', "[42000] [Microsoft][ODBC Microsoft Access Driver] Undefined function 'schema_name' in expression. (-3102) (SQLExecDirectW)")
[SQL: SELECT schema_name()]
(Background on this error at: http://sqlalche.me/e/14/f405)
Edit 2
copied what was stated here: https://github.com/gordthompson/sqlalchemy-access/wiki/Getting-Connected#connecting-with-an-odbc-connection-string
so the code looks this now:
import msaccessdb
import pandas as pd
from sqlalchemy import create_engine
import urllib
db_file = r'database\sampledatabase.accdb'
input_csv_file= r'database\sample_data.csv'
msaccessdb.create(db_file)
connection_string = (
r'DRIVER={{Microsoft Access Driver (*.mdb, *.accdb)}};'
r'DBQ=database\sample_data.csv;'
r'ExtendedAnsiSQL=1;'
)
connection_uri = f"access+pyodbc:///?odbc_connect={urllib.parse.quote_plus(connection_string)}"
engine = create_engine(connection_uri)
input_data=pd.read_csv(input_csv_file)
input_data.to_sql('sample_table', engine, index=False, if_exists='replace')
but I am still getting this error:
(pyodbc.Error) ('IM012', '[IM012] [Microsoft][ODBC Driver Manager] DRIVER keyword syntax error (0) (SQLDriverConnect)')
(Background on this error at: http://sqlalche.me/e/14/dbapi)
it should be noted that I have installed Access on my system.
You have two sets of curly brackets surrounding the driver name …
connection_string = (
r'DRIVER={{Microsoft Access Driver (*.mdb, *.accdb)}};'
r'DBQ=database\sampledatabase.accdb;'
r'ExtendedAnsiSQL=1;'
)
connection_uri = f"access+pyodbc:///?odbc_connect={urllib.parse.quote_plus(connection_string)}"
engine = create_engine(connection_uri)
… but because you are using an r'string' (not an f'string') you should only have one pair of curly brackets:
connection_string = (
r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
r'DBQ=database\sampledatabase.accdb;'
r'ExtendedAnsiSQL=1;'
)
connection_uri = f"access+pyodbc:///?odbc_connect={urllib.parse.quote_plus(connection_string)}"
engine = create_engine(connection_uri)

Unable To Connect mdb VIEW Table via pyodbc Python

I am now facing a difficulty connecting VIEW table in mdb file using pyodbc.
Current code is as follows:
(Previous Provider: Microsoft.Jet.OLEDB.4.0)
import pyodbc
pyodbc.pooling = False
conn_str = (
r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
r'DBQ=C:***.mdb;'
)
cnxn = pyodbc.connect(conn_str)
crsr = cnxn.cursor()
for table_info in crsr.tables(tableType='TABLE'):
print(table_info.table_name)
strSQL = "SELECT A,B FROM tableC WHERE ** ORDER BY B"
crsr.execute(strSQL)
for row in crsr.fetchall():
print(row)
When it works, for table_info in crsr.tables(tableType='TABLE'): seems to have no issue.
This is because print(table_info.table_name) displays several table names.
However, when crsr.execute(strSQL) is done, exeption error has raised and following message
('HY000', "[HY000] [Microsoft][ODBC Microsoft Access Driver] ODBC--connection to 'VIEW' failed. (-2001) (SQLExecDirectW)")
is shown.
It would be appreciated to instruct me how to overcome this issue.
Thanks.

Accessing Global Temporary Table through pyodbc

I am operating a python 3 notebook in Azure Data Studio (similar to jupyter notebook) and trying to access an existing global temp table (##TEMP1) via pyodbc.
Here is my code:
import pandas as pd
import pyodbc
con = pyodbc.connect(
Trusted_Connection="yes",
driver="{ODBC Driver 17 for SQL Server}",
host="SERVERNAME",
database=db,
trustServerCertificate="yes",
multisubnetfailover="yes",
applicationIntent="ReadOnly",
)
sql = """
select * from ##TEMP1
"""
data = pd.read_sql(sql, con)
con.close()
data.head()
In Azure Data Studio, when I switch the kernel to sql and simply query select * from ##TEMP1, it returns results, however when I try to run via the python code above via pyodbc, it's returning the following error.
DatabaseError: Execution failed on sql ' select * from ##TEMP1 ':
('####', "[####] [Microsoft][ODBC Driver 17 for SQL Server][SQL
Server]Invalid object name '##TEMP1'. (###) (SQLExecDirectW)")
Please help, those much smarter than I! :)
I think you want something like this:
I use pyodbc to make the connection and query the database. As you can see I create a curser with pyodbc and execute the curser with the SQL query string as an argument. Then use fetchall() to return the result for the curser
import pandas as pd
import pyodbc
con = pyodbc.connect(Trusted_Connection='yes', driver = '{ODBC Driver 17 for SQL Server}',host = 'SERVERNAME', database = db,trustServerCertificate='yes',multisubnetfailover='yes',applicationIntent='ReadOnly')
crsr = conn.cursor()
sql = '''
select * from ##TEMP1
'''
crsr.execute(sql)
results = crsr.fetchall()
con.close()
data.head()

"Cannot find data type READONLY" error on UPDATE to SQL Server

I've been stuck in this problem for a long time, i hope somebody could enlighten me. I have a sql database i would like to update. Here are some pieces of the code. I extracted data from sql to Python, then apply function hex_to_string & slicing bin and I plan to update the SQL database. I don't have any ID in the database, but I have the DATETIME which differentiates the entry.
query = """ select P from Table """
cnxn = pyodbc.connect(conn_str)
cnxn.add_output_converter(pyodbc.SQL_VARBINARY, hexToString)
cursor: object = cnxn.cursor()
cursor.execute(query)
dtbs= cursor.fetchall()
row_list=[]
ln = len(dtbs)
cursor.execute(query)
for i in range(ln):
row=cursor.fetchval()
result=slicing_bin(row)
result_float = [float("{0:.2f}".format(i)) for i in result]
row_list.append(result_float)
crsr = cnxn.cursor()
crsr.execute(query)
aList = [item[0] for item in crsr.fetchall()]
for aValue in aList:
crsr.execute("""UPDATE Table SET P=? WHERE DATETIME=?""", (row_list, aValue))
crsr.close()
cnxn.commit()
When I run this code, I got an error message,
File
"C:/Users/r/.PyCharmCE2018.3/config/scratches/Finalcombined2.py",
line 64, in
crsr.execute("""UPDATE Access.dbo.M_PWA SET P_PULSES=? WHERE DATETIME=?""", (row_list, aValue)) pyodbc.ProgrammingError: ('42000',
"[42000] [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Column,
parameter, or variable #1: Cannot find data type READONLY. (2715)
(SQLExecDirectW); [42000] [Microsoft][ODBC Driver 11 for SQL
Server][SQL Server]Statement(s) could not be prepared. (8180); [42000]
[Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Parameter or
variable '#P1' has an invalid data type. (2724)")
Please Help, thanks.
Hummm, I would have guessed that Gord was right. That's certainly the first thing I'd look at. Ok, here is a small sample of how I do updates in MS Access, from Python.
#import pypyodbc
import pyodbc
# MS ACCESS DB CONNECTION
pyodbc.lowercase = False
conn = pyodbc.connect(
r"Driver={Microsoft Access Driver (*.mdb, *.accdb)};" +
r"Dbq=C:\\path_here\\Northwind.mdb;")
# OPEN CURSOR AND EXECUTE SQL
cur = conn.cursor()
# Option 1 - no error and no update
cur.execute("UPDATE dbo_test SET Location = 'New York' Where Status = 'Scheduled'");
conn.commit()
cur.close()
conn.close()
Can you adapt this to your specific scenario?

Categories