Python sqlalchemy catch sql message - python

Working with Python and SQL Server I'm trying to catch the SQL Messages (PRINT or RAISERROR) that may ossure when exeuting SQL command or stored procedure.
On the SQL Server I have the following procedure (simplified for my question)
CREATE PROCEDURE dbo.pyTest (#n int)
AS
SET NOCOUNT ON
IF OBJECT_ID('dbo.tablename') IS NULL RAISERROR(N'Error. Destination table not found.',0,0)
ELSE INSERT INTO dbo.tablename VALUES (#n);
In Python I'm executing this script
server = 'server_name'
db = 'database_name'
from sqlalchemy import create_engine
engine = create_engine(f"mssql+pyodbc://{server}/{db}?trusted_connection=yes&driver=ODBC+Driver+17+for+SQL+Server")
query="INSERT INTO dbo.tablename VALUES (1)"
#query="SELECT GETDATE()"
with engine.begin() as conn:
conn.execute(query)
My question is: How do I catch the messages being produced from the stored procedure?
When I execute "EXEC dbo.pyTest 1" in SSMS
I get the following text in the Messages tab
"Error. Destination table not found."
But when I do the same in Python I get "Process finished with exit code 0"
I have been reading a lot of suggestions from Goggle, but have not been able to find similar question.

Related

How to commit stored procedure execution by using pyodbc

I am trying to execute stored procedure by using pyodbc in databricks, after executing SP I tried to commit the connection but, commit is not happening. Here I am giving my code, please help me out from this issue.
import pyodbc
#### Connecting Azure SQL
def db_connection():
try:
username = "starsusername"
password = "password-db"
server = "server-name"
database_name = "db-name2"
port = "db-port"
conn=pyodbc.connect('Driver={ODBC Driver 17 for SQL server};SERVER=tcp:'+server+','+port+';DATABASE='+ database_name +';UID='+ username +';PWD='+ password)
cursor=conn.cursor()
return cursor, conn
except Exception as e:
print("Faild to Connect AZURE SQL: \n"+str(e))
cursor, conn = db_connection()
# conn1.autocommit=True
cursor.execute("delete from db.table_name")
cursor.execute("insert into db.table_name(BUSINESS_DATE) values('2021-10-02')")
cursor.execute("exec db.SP_NAME '20211023'")
conn.commit()
conn.close()
here I am commiting connection after SP excution. deletion and insertion is not happening at all. and I tried with cursor.execute("SET NOCOUNT ON; exec db.SP_NAME '20211023'") but it's also not working.
Thanks in Advance
If you check this document on pyodbc, you will find that -
To call a stored procedure right now, pass the call to the execute method using either a format your database recognizes or using the ODBC call escape format. The ODBC driver will then reformat the call for you to match the given database.
Note that after connection is set up or done, try doing conn.autocommit = True before calling your SP and it will help. By default it is false.
Executing the Stored Procedure.
You will be able to execute your stored procedure if you follow the below code snippet.
cursor = conn.cursor()
conn.autocommit = True
executesp = """EXEC yourstoredprocedure """
cursor.execute(executesp)
conn.commit()
Delete the Records in SQL Server
You can delete record as shown in the below example.
...#just an example
cursor.execute('''
DELETE FROM product
WHERE product_id in (5,6)
''')
conn.commit()
Don’t forget to add conn.commit() at the end of the code, to ensure that the command would get executed.
Insert record in SQL Server
The below snippet show how we can do the same.
...#just an example
cursor.execute("INSERT INTO EMP (EMPNO, ENAME, JOB, MGR) VALUES (535, 'Scott', 'Manager', 545)")
conn.commit()
I will suggest you to read the for following document for more information.
Delete Record Documentation.
Insert Record Document

Python SQL Script - How to send email with error

I've built a Python script that runs a report for me using one of our vendor's API's, then uploads the data directly to an MS SQL server. I would like to add an error handler that sends an email when the insert fails for any reason.
Can I just wrap my insert statement in a try? Currently I have this going to a local server for testing...
conn = pyodbc.connect('Driver={SQL Server};'
'Server=localhost\*****local;'
'Database=Reporting;'
'Trusted_Connection=yes;')
#Set cursor variable
cursor = conn.cursor()
executeValue = """INSERT INTO New_Five9_CallLog
(Call_ID, [Timestamp],
Campaign, Call_Type, Agent_Email, Agent_Name, Disposition,
ANI, Customer_Name, DNIS, Call_Time, Rounded_Bill_Time,
Cost, IVR_Time, Queue_Wait_Time, QCB_Wait_Time,
Total_Queue_Time, Ring_Time, Talk_Time, Hold_Time, Park_Time,
ACW_Time, Transfers, Conferences, Holds, Parks, Abandoned,
Recordings, Handle_Time, Session_ID, IVR_Path,
Skill, Ticket_Number)
VALUES (""" + values + ")"
#Execute query
cursor.execute(executeValue)
#Commit and close
conn.commit()
conn.close()
I get the values variable with some other script above this section. What I'd like to know is how to capture an error on this section and then send an email to myself with the error description.
Check out this answer https://stackoverflow.com/a/42143703/1525867 explaining how to catch pyodbc specific errors (I personally use https://sendgrid.com/ to send emails)

Python & SQL Server stored procedure hang

I am trying to get Python to run a stored procedure in my SQL Server which kicks off a series of procedures which involves importing a file processing it and outputting a couple of files.
So far I have got my code so that it accepts an input to a table but then the whole thing hangs when it calls the stored procedure.
Checking Who2 on the server it is waiting on the preemptive_OS_Pipeops which searching has revealed it is waiting on something outside of SQL Server to finish before proceeding.
Is someone able to shed some light if it is possible to use pyodbc to blind activate a stored procedure then close the connection?
My belief is by just telling the procedure to run then closing out should fix the issue but I am having issues finding the code for this
Python code:
connection2 = pypyodbc.connect('Driver={SQL Server}; Server=server;Database=db', timeout=1)
cursor2 = connection2.cursor()
cursor2.execute("{CALL uspGoBabyGo}")
connection2.close()
return 'file uploaded successfully'
Stored procedure:
BEGIN
SET NOCOUNT ON;
EXECUTE [dbo].[uspCableMapImport]
END
After searching and the script stopped posting the record to the table I found the solution to the issue. I needed to add in the autocommit=True line to the script, now the code is as follows;
connection = pyodbc.connect('Driver={SQL Server};
Server='Server';Database='DB';Trusted_Connection=yes')
connection.autocommit=True
cursor = connection.cursor()
referee = file.filename.rsplit('.')[0]
SQLCommand = ("INSERT INTO RequestTable(Reference, Requested) VALUES ('"+ str(referee) +"', " + datetime.now().strftime('%Y-%m-%d') + ")")
cursor.execute(SQLCommand)
connection.commit
SQLCommand2 = ("{CALL uspGoBabyGo}")
cursor.execute(SQLCommand2)
connection.commit
connection.close()

Create a schema in SQL Server using pyodbc

I am using pyodbc to read from a SQL Server database and create analogous copies of the same structure in a different database somewhere else.
Essentially:
for db in source_dbs:
Execute('create database [%s]' % db) # THIS WORKS.
for schema in db:
# The following result in an error starting with:
# [42000] [Microsoft][ODBC SQL Server Driver][SQL Server]
Execute('create schema [%s].[%s]' % (db, schema)
# Incorrect syntax near '.'
Execute('use [%s]; create schema [%s]' %(db, schema)
# CREATE SCHEMA' must be the first statement in a query batch.
In this example, you can assume that Execute creates a cursor using pyodbc and executes the argument SQL string.
I'm able to create the empty databases, but I can't figure out how to create the schemas within them.
Is there a solution, or is this a limitation of using pyodbc with MS SQL Server?
EDIT: FWIW - I also tried to pass the database name to Execute, so I could try to set the database name in the connection string. This doesn't work either - it seems to ignore the database name completely.
Python database connections usually default to having transactions enabled (autocommit == False) and SQL Server tends to dislike certain DDL commands being executed in a transaction.
I just tried the following and it worked for me:
import pyodbc
connStr = (
r"Driver={SQL Server Native Client 10.0};"
r"Server=(local)\SQLEXPRESS;"
r"Trusted_connection=yes;"
)
cnxn = pyodbc.connect(connStr, autocommit=True)
crsr = cnxn.cursor()
crsr.execute("CREATE DATABASE pyodbctest")
crsr.execute("USE pyodbctest")
crsr.execute("CREATE SCHEMA myschema")
crsr.close()
cnxn.close()

Unknown Database Error python mysql

This link contains shows the database I've created in the mysql workbench and the connection I have established in the code but the database is unknown for some reason. Is there a step I've missed?
http://gyazo.com/d995c4da99043da43bfbd057a0a839c7
__author__ = 'avi'
from TwitterSearch import *
import json
twtsearch = TwitterSearch(
consumer_key='PXTUrlRfgC1zSTsAPU9z6EHtD',
consumer_secret='qM9F4FVj1qLFc6f795r96DQPNAJO8hkbWy4PXWYLfQcYyNGY7D',
access_token='2943116292-wVHEjbfjX7OFqaOURBqim5o7Vs6lZyjxsoto8nD',
access_token_secret='CJAppSRY9TZ5cwYTABZhH2YTd0rm5IzBDqPder6v4qLBA'
)
twtsearchorder = TwitterSearchOrder()
twtsearchorder.set_keywords(['iphone6'])
twtsearchorder.set_language('en')
twtsearchorder.set_include_entities(True)
tweet_limit=50
parsed_tweets= {}
table="twtinfo"
import MySQLdb as mdb
con = mdb.connect('localhost', 'root','root','tweetinfo')
cur=con.cursor()
for tweet in twtsearch.search_tweets_iterable(twtsearchorder):
if tweet_limit > 0 :
parsed_tweets['name'] = tweet['user']['screen_name']
parsed_tweets['content'] = tweet['text']
parsed_tweets['user_id'] = tweet['user']['id']
parsed_tweets['fav_count'] = tweet['favorite_count']
parsed_tweets['location'] = tweet['user']['location']
parsed_tweets['retweet_count'] = tweet['retweet_count']
placeholders= ', '.join(['%s'] *len(parsed_tweets))
columns = ', '.join(parsed_tweets.keys())
sql="INSERT into %s ( %s ) VALUES ( %s )" % (table, columns, placeholders)
cur.execute(sql,parsed_tweets.values())
tweet_limit -= 1
The MySQL process is complaining about the database you are trying to access, namely tweetinfo isn't existing. MySQL error 1049 is usually an indication of having to forgot to select a database, but you did as forth argument to mdb.connect()
Possible errors could be:
That you have several MySQL processes running, with the one with the proper database not being on the default MySQL port.
That somehow your database GUI application hasn't actually submitted your database and table to the MySQL process.
That MySQL isn't running? You would probably get a different error message for that, but it could be an idea to make sure it is just in case.
Just to check if your tables exists and that your database is in place, open a terminal and write the following commands:
mysql -u root -proot
use tweetinfo;
show create table twtinfo;
Another thing to try could be to ask the MySQL process about which database it thinks you are using. Try adding something like the following to your code:
cur.execute("SELECT DATABASE() FROM DUAL;")
print("Database is: %s.", cur.fetchone()[0])
I'm not a python programmer, so I'm not entirely confident that will work without some adjustments.
If none of this gave you a good lead, I'm not quite sure what's wrong.

Categories

Resources