I'd like to catch any type of error in Python3.
I'm trying something like that:
try:
fields = line.split(' ')
...
<PostgreSQL query execution>
except psycopg2.Error:
conn.rollback()
QUERY = "UPDATE table SET error='sql'"
cur = conn.cursor()
cur.execute(QUERY)
conn.commit()
cur.close()
continue
except:
conn.rollback()
e="generic"
QUERY = "UPDATE table SET error='generic'"
cur = conn.cursor()
cur.execute(QUERY)
conn.commit()
cur.close()
continue
But I noted that, for example, an IndexError is not caught and the script fails.
What's wrong?
Thanks!
This happens when a new exception occurs in the except block.
For example:
try:
print('foo')
raise ValueError
except:
print('noes!')
print(1/0)
Will exit with divide by zero exception.
In order to see if it is so, we need more of actual code from you, particularly both of the except blocks.
If you want to make sure you catch "any" exception, make sure your except blocks are unexceptional.
Related
I am starting to learn Python, and I wrote a very simple code to practice try/except.
Here is the code:
a = float(input('num1: '))
b = float(input('num2: '))
try:
result = a / b
except ValueError as e:
print ('error type: ', type (e))
print(result)
Whenever I enter a letter as a number, the print in except is working, but the code crashes.
ZeroDivisionError & TypeError are working, but ValueError is not.
I even put inputs in separate try/except and it is still not working.
How can I handle this error here, and in the real app?
The crash is occurring before you enter the try block. It does not print the error in the except block if you enter a letter with your current code.
Simply putting the input section in a separate try block wouldn't catch it - you need an except block related to the try within which the error is happening, e.g.
try:
a = float(input('num1: '))
b = float(input('num2: '))
except ValueError as e:
print ('Value Error')
try:
result = a / b
except ZeroDivisionError as e:
print ('Zero DivisionError')
print(result)
Alternatively, you could put the input and division all within the try block and catch with your current reporting:
try:
a = float(input('num1: '))
b = float(input('num2: '))
result = a / b
except ValueError as e:
print ('error type: ', type (e))
print(result)
EDIT: Note that if any error does occur in either of these, it will cause further errors later on. You're better off going with the second option, but moving the print(result) into the try block. That's the only time it will be defined.
I have to define an attribute in a class and I would like to manage error in the most pythonic way.
Here is the code I have tried so far. I can't figure out why I can not "reach" the exception in the following code.
# global variable to be used in the example
my_dict = {"key1": {"property": 10}, "key2": {}}
class Test(object):
#property
def my_attribute(self):
try:
return self._my_attribute
except AttributeError:
self._my_attribute = {}
for key, value in my_dict.items():
print(key)
self._my_attribute[key] = value['property']
except Exception:
print('error')
# I would like to manage my error here with a log or something
print("I am not reaching here")
finally:
return self._my_attribute
if __name__ == '__main__':
Test().my_attribute
I expected to reach the Exception case in the second iteration of the for loop since it is a KeyError ("key2" has no "property"). But it just passes by it. In this example, if the script is run, it does not print "I am not reaching here". Could anyone explain why I am seeing this wrong? Thanks!
The potential KeyError in self._my_attribute[key] = value['property'] is not covered by the except Exception block. Once it is raised the finally block is executed (as a matter of fact the finally block is always executed, regardless of an exception being raised or even handled). This can be easily verified by using a step-by-step debugger or with a simple print('finally') inside the finally block.
This is (among other reasons) why try blocks should be as minimal as possible. If you know that line might raise a KeyError then explicitly try-except it:
for key, value in my_dict.items():
print(key)
try:
self._my_attribute[key] = value['property']
except KeyError as e:
print('Key ', e, 'does not exist')
So I've queried data from oracle database using cursor.execute(). A relatively simple select query. It works.
But when I try to fetch data from it, python crashes.
The same occurs for fetchall(), fetchmany() and fetchone().
When the query first broke in fetchmany() I decided to loop through fetchone() and it worked for the first two rows then broke at the third.
I'm guessing it is because there's too much data in third row.
So, is there any way to bypass this issue and pull the data?
(Please ignore the wrong indents could not copy properly in my phone)
EDIT:
I removed four columns with type "ROWID". There was no issue after that. I was easily able to fetch 100 rows in one go.
So to confirm my suspicion I went ahead and created another copy with only those rowed columns and it crashes as expected.
So is there any issue with ROWID type?
Test table for the same.
Insert into TEST_FOR_CX_ORACLE (Z$OEX0_LINES,Z$OEX0_ORDER_INVOICES,Z$OEX0_ORDERS,Z$ITEM_ROWID) values ('ABoeqvAEyAAB0HOAAM','AAAL0DAEzAAClz7AAN','AAAVeuABHAAA4vdAAH','ABoeo+AIVAAE6dKAAQ');
Insert into TEST_FOR_CX_ORACLE (Z$OEX0_LINES,Z$OEX0_ORDER_INVOICES,Z$OEX0_ORDERS,Z$ITEM_ROWID) values ('ABoeqvABQAABKo6AAI','AAAL0DAEzAAClz7AAO','AAAVeuABHAAA4vdAAH','ABoeo+AIVAAE6dKAAQ');
Insert into TEST_FOR_CX_ORACLE (Z$OEX0_LINES,Z$OEX0_ORDER_INVOICES,Z$OEX0_ORDERS,Z$ITEM_ROWID) values ('ABoeqvABQAABKo6AAG','AAAL0DAEzAAClz7AAP','AAAVeuABHAAA4vdAAH','ABoeo+AHIAAN+OIAAM');
Insert into TEST_FOR_CX_ORACLE (Z$OEX0_LINES,Z$OEX0_ORDER_INVOICES,Z$OEX0_ORDERS,Z$ITEM_ROWID) values ('ABoeqvAEyAAB0HOAAK','AAAL0DAEzAACl0EAAC','AAAVeuABHAAA4vdAAH','ABoeo+AHIAAN+OIAAM');
Script:
from cx_Oracle import makedsn,connect,Cursor
from pandas import read_sql_table, DataFrame, Series
from time import time
def create_conn( host_link , port , service_name , user_name , password ):
dsn=makedsn(host_link,port,service_name=service_name)
return connect(user=user_name, password=password, dsn=dsn)
def initiate_connection(conn):
try:
dbconnection = create_conn(*conn)
print('Connected to '+conn[2]+' !')
except Exception as e:
print(e)
dbconnection = None
return dbconnection
def execute_query(query,conn):
dbconnection=initiate_connection(conn)
try:
cursor = dbconnection.cursor()
print ('Cursor Created!')
return cursor.execute(query)
except Exception as e:
print(e)
return None
start_time = time()
query='''SELECT * FROM test_for_cx_oracle'''
try:
cx_read_query = execute_query(query,ecspat_c)
time_after_execute_query = time()
print('Query Executed')
columns = [i[0] for i in cx_read_query.description]
time_after_getting_columns = time()
except Exception as e:
print(e)
print(time_after_execute_query-start_time,time_after_getting_columns-time_after_execute_query)
Unfortunately, this is a bug in the Oracle Client libraries. You will see it if you attempt to fetch the same rowid value multiple times in consecutive rows. If you avoid that situation all is well. You can also set the environment variable ORA_OCI_NO_OPTIMIZED_FETCH to the value 1 before you run the query to avoid the problem.
This has been reported earlier here: https://github.com/oracle/python-cx_Oracle/issues/120
I tried to get executed with my except: statement... while attempt to oppose the functionality of UNIQUE constraint..But ended with exceptional error..
The Postgresql database table already contains the row that I have used in
db.insert("The News","AparnaKumar",1995,234569654)
but it works well on inserting unrepeated rows..
import psycopg2
class database:
def __init__(self):
self.con=psycopg2.connect("dbname='book_store' user='postgres' password='5283' host='localhost' port='5432' ")
self.cur=self.con.cursor()
self.cur.execute("CREATE TABLE if not exists books(id SERIAL PRIMARY KEY,title TEXT NOT NULL UNIQUE,author TEXT NOT NULL,year integer NOT NULL,isbn integer NOT NULL UNIQUE)")
self.con.commit()
def insert(self,title,author,year,isbn):
try:
self.cur.execute("INSERT INTO books(title,author,year,isbn) VALUES(%s,%s,%s,%s)",(title,author,year,isbn))
self.con.commit()
except:
print("already exists..")
def view(self):
self.cur.execute("SELECT * FROM books")
rows=self.cur.fetchall()
print(rows)
def search(self,title=None,author=None,year=None,isbn=None):
self.cur.execute("SELECT * FROM books WHERE title=%s or author=%s or year=%s or isbn=%s",(title,author,year,isbn))
row=self.cur.fetchall()
print(row)
db=database()
db.insert("The News","AparnaKumar",1995,234569654)
db.view()
db.search(year=1995)
You can either modify your python function to rollback the transaction, or modify the sql to not insert a new row if a conflict occurs (postgresql versions 9.5+):
option 1:
def insert(self,title,author,year,isbn):
try:
self.cur.execute("INSERT INTO books(title,author,year,isbn) VALUES(%s,%s,%s,%s)",(title,author,year,isbn))
self.con.commit()
except:
self.con.rollback()
print("already exists..")
option 2 (works for postgresql versions 9.5 or later):
def insert(self,title,author,year,isbn):
try:
self.cur.execute("INSERT INTO books(title,author,year,isbn) VALUES(%s,%s,%s,%s) ON CONFLICT DO NOTHING",(title,author,year,isbn))
self.con.commit()
except:
print("already exists..")
Use a SAVEPOINT.
See the second question in the psycopg FAQ list.
If you want to keep an transaction open, you should use a SAVEPOINT and ROLLBACK to that SAVEPOINT when the exception occurs. But since you use a catchall exception (too broad), this will also happen on other errors. So it gets a bit out of control.
Perhaps a very simple solution is to check using a SELECT if the record you're about to insert already exists.
I am trying to write a function to do a simple insert.
Here is what I have tried so far
#! /usr/bin/env python3
#import
import sqlite3 as lite
#trying an insert version 1 (does nothing)
def createTableTask():
"""
Create a new table with the name Task
"""
#Connnection to the database and cursor creation
con = lite.connect('./exemple.sqlite')
con.row_factory = lite.Row
cur = con.cursor()
#that does nothing
try:
cur.execute('''CREATE TABLE Tasks (\
Name TEXT PRIMARY KEY, \
Description TEXT, \
Priority TEXT);''')
except lite.IntegrityError as error_SQLite:
print("error: "+ str(error_SQLite))
else:
print("No error has occured.")
con.close();
def insert1():
"""
insert a new task
"""
#Allocating variables data
taskName = 'finish code'
taskDescription = 'debug'
taskPriority = 'normal'
#Connnection to the database and cursor creation
con = lite.connect('./exemple.sqlite')
con.row_factory = lite.Row
cur = con.cursor()
#that does nothing
try:
with con:
cur.execute('''INSERT INTO Tasks (Name, Description, Priority) \
VALUES (?, ?, ?)''', (taskName, taskDescription, taskPriority))
except lite.IntegrityError as error_SQLite:
print("error: "+ str(error_SQLite))
else:
print("No error has occured. but no insert happend ?")
con.close();
def showResult():
"""
Show the result of the insert
"""
con = lite.connect('./exemple.sqlite')
con.row_factory = lite.Row
cur = con.cursor()
cur.execute\
('''SELECT * FROM Tasks ;''')
row = cur.fetchone()
while row:
print(row["Name"], ' | ', row["Description"], ' | ', \
row["Priority"])
row = cur.fetchone()
con.close();
#trying an insert version 2 (this one crash giving :Value error)
def insert2():
"""
insert a new task
"""
#Allocating variables data
taskName = 'finish code'
taskDescription = 'debug'
taskPriority = 'normal'
#Connnection to the database and cursor creation
con = lite.connect('./exemple.sqlite')
con.row_factory = lite.Row
cur = con.cursor()
queryInsert = ('''INSERT INTO Tasks (Name, Description, Priority) \
VALUES (?, ?, ?)''', (taskName, taskDescription, taskPriority))
try:
with con:
cur.execute(queryInsert)
except lite.IntegrityError as error_SQLite:
print("error: "+ str(error_SQLite))
else:
print("No error has occured.")
con.close();
def run():
createTableTask()
insert1()
showResult()
insert2()
showResult()
#calling section
run()
The problem is that none of the insert that I have made so far worked.
The first one does actualy nothing but has a correct syntax
The second one, well it crash.
Here is the output:
spark#spark-Razer-Blade-Pro:~/Documents/testing$ ./exemp.py
No error has occured.
No error has occured. but no insert happend ?
Traceback (most recent call last):
File "./exemp.py", line 98, in
run()
File "./exemp.py", line 94, in run
insert2()
File "./exemp.py", line 83, in insert2
cur.execute(queryInsert)
ValueError: operation parameter must be str
spark#spark-Razer-Blade-Pro:~/Documents/testing$ sqlite3 exemple.sqlite
SQLite version 3.8.2 2013-12-06 14:53:30
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> SELECT * FROM Tasks;
sqlite>
I am looking for the most simple fix and maybe know what is wrong with my code. Because Right now I do not know what is going on with the no insert one. Normally it should, or am I missing something ?
queryInsert = ('''INSERT ...''', (taskName, taskDescription, taskPriority))
This makes queryInsert a tuple with two elements.
But to call the execute method, you need two separate parameters.
You could just unpack the tuple:
cur.execute(*queryInsert)
but it might be clearer to use two separate variables:
queryString = '''INSERT ...'''
queryParams = (taskName, taskDescription, taskPriority)
cur.execute(queryString, queryParams)
ok I got around my error. Just posting it because it might help others.
cur.execute() is a fonction that seek a query as it's first argument, than the other argument are the variables needed for the query.
step one: make the query into a variable without it's parameters
queryString = ''' INSERT INTO someTables rowName, rowName2 ... VALUES (?, ?);'''
there should be as much as ? as there are variables needed. in this exemple I need 2
queryValue1 = 'something'
queryValue2 = '123'
Step 2 to call and execute the query :
cur.execute(queryString, queryValue1, queryValue2)
this should be working without problem