try & except pyodbc with no internet connection - python

I am writing and reading from a sql database with tries & excepts. The thought behind the try/except is if for some reason the internet is down or we cannot connect to the server, we will write the sql transactions locally to a text file and then use those statements to update the table. That being said - the try and except only seems to work if there is a connection to the server. We have a table BAR in the DB database on server FOO:
try:
conn = pyodbc.connect('DRIVER={SQL Server};SERVER=FOO;DATABASE=DB;UID=user;PWD=password')
cursor = conn.cursor()
cursor.execute("UPDATE BAR SET Date = '"+time+"' WHERE ID = "+ID)
conn.commit()
except:
f = open("vistorlog.txt", "a")
f.write("UPDATE BAR SET Date = '"+time+"' WHERE ID = "+ID+"\n")
f.close()
the only instance where this try&except works is when there is an issue with the sql statement i.e. "Update BARS..." fails because there is no table named BARS. If I change the server to FOOS (or in a real life scenario unplug the ethernet cord and leave the table/serve names legitimate) the try and except doesn't work - the program freezes with no error.

Related

Psycopg2 cannot connect to a server

I was writing a proprietary script that queries a company database to pull certain information. I was using Psycopg2. At this point the lines I was using were like:
conn = psycopg2.connect("dbname='somedb' user='usr' host='something.azure.com' password='pswd' port='5432'")
cur = conn.cursor()
query = "something"
cur.execute(query)
results = cur.fetchall()
The script was running fine until a few days ago, after quick successions of runs during debugging, I started getting:
psycopg2.OperationalError: server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
A closer look that I realized I did not properly close the connection. So I modified it to:
with psycopg2.connect("dbname='somedb' user='usr' host='something.azure.com' password='pswd' port='5432'") as conn:
cur = conn.cursor()
query = "something"
cur.execute(query)
results = cur.fetchall()
The error persisted even when no additional connections were present on the server end, so hitting max_connection is unlikely the reason here.
Strangely, I can access the same server through PGAdmin or use sqlalchemy.create_engine with pandas.read_sql on the same machine. Additionally, the script runs fine on another colleague's machine while mimicking my IP address through VPN.
Edit: sqlalchemy worked for my machine for exactly once, after which I started to get the same error.
My sqlalchemy code:
engine = create_engine('postgresql://{0}:{1}#{2}:5432/db'.format(USR, PSWD, HOST))
query = "something"
df = pd.read_sql(sql=query, con=engine)

How to properly organise the database calls with Python and MySQL?

I have a code like this:
import mysql.connector as mysql
from generate_records import generateRecords
devicesQuery = "CALL iot.sp_sensors_overview()"
try:
db = mysql.connect(
user = "username",
password = "password",
host = "hostname",
database="iot"
)
cursor = db.cursor(dictionary=True, buffered=True)
cursor.execute(devicesQuery)
for sensor in cursor:
generateRecords(sensor, db)
cursor.close()
except mysql.connector.Error as error:
print("Error:")
print(error)
else:
db.close()
The purpose of generateRecords function is obviously to generate records and run the INSERT query against the different table.
Seems like I do something wrong, because no matter what I trying, I getting different errors here, like mysql.connector.errors.OperationalError: MySQL Connection not available..
(upd) I also tried to change the code like it was suggested (see example bellow), with no luck - I still receiving the MySQL connection not available. error.
rows = cursor.fetchall()
cursor.close()
for sensor in rows:
cursor2 = db.cursor()
generateRecords(sensor, cursor2)
So, should I create a new connection within generateRecords function, or pass something different within it, or use some kind of different approach here?
Thank you!
Finally I found what was wrong. I'm used the query to call the stored procedure. Using the cursor.callproc("sp_sensors_overview") instead fixed my issue, and now I'm able to create the next cursor without errors.

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: cx_Oracle cursor.execute() hangs on UPDATE query

I have looked at similar questions but nothing has worked for me so far
So here it is. I want to update my table through a python script. I'm using the module cx_oracle. I can execute a SELECT query but whenever I try to execute an UPDATE query, my program just hangs (freezes). I realize that I need to use cursor.commit() after cursor.execute() if I am updating a table but my code never gets past cursor.commit(). I have added a code snippet below that I am using to debug.
Any suggestions??
Code
import cx_Oracle
def getConnection():
ip = '127.0.0.1'
port = 1521
service_name = 'ORCLCDB.localdomain'
username = 'username'
password = 'password'
dsn = cx_Oracle.makedsn(ip, port, service_name=service_name) # (CONNECT_DATA=(SERVICE_NAME=ORCLCDB.localdomain)))
return cx_Oracle.connect(username, password, dsn) # connection
def debugging():
con = getConnection()
print(con)
cur = con.cursor()
print('Updating')
cur.execute('UPDATE EMPLOYEE SET LATITUDE = 53.540943 WHERE EMPLOYEEID = 1')
print('committing')
con.commit()
con.close()
print('done')
debugging()
**Here is the corresponding output: **
<cx_Oracle.Connection to username#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCLCDB.localdomain)))>
Updating
Solution
After a bit of poking around, I found the underlying cause! I had made changes to the table using Oracle SQL Developer but had not committed them, when the python script tried to make changes to the table it would freeze up because of this. To avoid the freeze, I committed my changes in oracle sql developer before running the python script and it worked fine!
Do you have any option to look in the database ? I mean , in order to understand whether is a problem of the python program or not, we need to check the v$session in the database to understand whether something is blocked.
select sid, event, last_call_et, status from v$session where sid = xxx
Where xxx is the sid of the session which has connected with python.
By the way, I would choose to commit explicitly after cursor execute
cur.execute('UPDATE EMPLOYEE SET LATITUDE = 53.540943 WHERE EMPLOYEEID = 1')
con.commit()
Hope it helps
Best

How to refresh Mysql connection?

I have a program using Python + python mysql connector + Mysql which is installed in a network and uses the same database. How do I refresh a connection without restarting the program on other Machines?
The Program is installed in more than one Machine and connects to the same Mysql database which is located on a Server. The program is working properly, but,
when a new data is entered or modified "SQL INSERT, UPDATE.... Statments" from one machine is not reflected in all other Machines until the program is restarted, which means that a new connection is necessary to show the new database data.
So, I would like to know how to refresh the connection without restarting the program on other machines.
Here is the sample Connection code:
import mysql.connector as mc
conn = mc.connect(host='host', user='user', passwd='passw', db='db_name', port=port_number)
cur = conn.cursor()
How to refresh This Connection while the program is running?
closing and reopening connection may also solve your problem,
see following example in loop
import mysql.connector as mc
conn = mc.connect(host='host', user='user', passwd='passw', db='db_name', port=port_number)
while True:
# check if youre connected, if not, connect again
if (conn.is_connected() == False):
conn = mc.connect(host='host', user='user', passwd='passw', db='db_name', port=port_number)
cur = conn.cursor()
sql = "INSERT INTO db_name.myTable (name) VALUES (%(val)s);"
val = {'val':"Slim Shady"}
cur.execute(sql,val)
conn.commit()
conn.close()
After inserting or updating, you should do a commit to make sure all data it's writed to the DB. Then it will be visible for everyone:
conn.commit()

Categories

Resources