How to call exception in SQL sqlalchemy? - python

How to call exception for case if row was not found:
analys = Analyzes.query.filter_by(id=id).first()
I attempted to o this:
try:
analys = Analyzes.query.filter_by(id=id).first()
except NoResultFound as e:
return Response(str(e), status=400, mimetype='application/json')
It does not work for me...
Also I tried this:
if analys.count() == 0:
raise NameError('Protocol was not found!')

If .first() doesn't return anything, analys will be None, which you can treat as False, so:
analys = Analyzes.query.filter_by(id=id).first()
if not analys:
# We didn't get anything
raise NameError("Protocol was not found")
Or, as Ilja Everilä mentioned-- you could use .one if you expect only ever one result.
from sqlalchemy.orm.exc import NoResultFound
try:
analys = Analyzes.query.filter_by(id=id).one()
except NoResultFound:
print('Oh Noes!')

Related

Check if person's id exists in a function's dictionary

I have this code to check if a person exists given their id. If they do exist, it has to print the name and last name. If they don't exists, it has to print some error. The thing is, my code only prints the error even though I tried the code with a number I know corresponds to an existing person. How do I fix that?
This is my view:
from django.shortcuts import render, HttpResponse
import requests
from django.views.generic import FormView
from .forms import MonotributoForm
from app.ws_sr_padron import get_persona
class ConstanciaInscripcion(FormView):
def get(self, request):
return render(request, 'app/constancia-inscripcion.html')
def post(self,request):
form = MonotributoForm(request.POST)
try:
cuit_r = int(request.POST.get('cuit', '-1')) # Get 'cuit' with default of -1
except ValueError:
pass
response= get_persona(cuit_r)
if response is True:
print(response["persona"]['name'])
print(response['persona']['lastname'])
else:
print("cuit doesn't exist")
if form.is_valid():
cuit = form.cleaned_data.get('cuit')
email = form.cleaned_data.get('email')
cuit.save()
email.save()
return HttpResponseRedirect('app/constancia-inscripcion.html')
return render(request, 'app/constancia-inscripcion.html')
The code for get_persona (I cannot modify this as I did not write it and it was given to me this way):
def get_persona(cuit_requested, ta_sign=None, ta_token=None):
try:
if ta_sign is None and ta_token is None:
ta_sign, ta_token = wsaa.get_ta_sign_token('ws_sr_padron_a13')
client = Client(padron13_wsdl)
response = client.service.getPersona(
sign=ta_sign,
token=ta_token,
cuitRepresentada=cuit_consultante,
idPersona=cuit_requested,
)
return serialize_object(response, target_cls=dict)
except Fault as e:
if e.message == 'No person with Id':
return None
elif e.message == 'inactive':
return 'inactive'
print('Error: ', e)
return None
except Exception as e:
print('Error: ', e)
return None
Result of get_persona with an existing id (tried on terminal):
{'metadata': {'fechaHora': datetime.datetime(2021, 3, 4, 15, 13, 54, 738000, tzinfo=<FixedOffset '-03:00'>), 'servidor': 'linux11b'}, 'persona': {'apellido': 'POLAR', 'estadoClave': 'ACTIVO', 'idPersona': 2231230211, 'mesCierre': 12, 'nombre': 'MAURICIO', 'tipoClave': 'CUIT'}}
The output of response on it's own seems to be None for some reason.
The issue is due to the conditional in your code: if response is True.
If you look at the value that get_persona returns, it can be the result of the function serialize_object(...), None, or "inactive".
If the serialize_object(...) function returns a None or the string "inactive", the statement response is True will be false.
>>> type(True)
bool
>>> type({"a": 1})
dict
>>> type("inactive")
str
# To test this, I created this function
>>> def test_response(response):
return response is True
>>> test_response(None)
False
>>> test_response({"persona": True})
False
>>> test_response("inactive")
False
# The only value of response that `is True` is the value `True` itself!
>>> test_response(True)
True
What you want to do is change your conditional to check for a useful response value. In this case, you could test if the response value is a dict, but what if it doesn't have the persona value -- or what if the persona exists, but it doesn't have a nombre?
>>> response = {"a": 1}
>>> response["persona"]["nombre"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'persona'
>>> response = {"persona": None}
>>> response["persona"]["nombre"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not subscriptable
A better solution than an if statement would be a try/except, which can handle both types of errors gracefully and default to the invalid/error case.
response = get_persona(cuit_r)
try:
nombre = response["persona"]["nombre"]
apellido = response["persona"]["apellido"]
except KeyError:
nombre, apellido = None, None
print("get_persona response is missing keys!")
except TypeError:
nombre, apellido = None, None
print("get_persona response had wrong type!")
else:
print("get_persona returned a valid response!")
print("nombre:", nombre)
print("apellido:", apellido)
Update #1
Based on your comments, it also sounds like you're having trouble with the cuit_r value as well. You should change your code to properly handle the possible exceptions as separate statements:
try:
cuit_r = int(request.POST["cuit"])
except KeyError:
print("The key 'cuit' was missing from the POST data.")
print("Defaulting to cuit_r = -1")
cuit_r = -1
except TypeError:
print(
"The 'cuit' value is the wrong type:",
type(request.POST["cuit"]),
)
print("Defaulting to cuit_r = -1")
cuit_r = -1
print(f"Resolved value of cuit_r: {type(cuit_r).__name__}({cuit_r!r})")

how to continue processing after exception in python without aborting

I have a block of code where exception is happening for some records while executing an imported method (pls see below). My goal is NOT to stop execution, but perhaps print (to understand what's wrong with the data) some values when in error and continue. I tried various way to use "try...except", but no luck! Can someone pls take a look and suggest? Many thanks in advance!
code below
if student_name not in original_df_names_flat:
for org in orgs:
data = calculate(org, data)
result = imported_module.execute(data) # here's the line where exception happens
return result
else:
return data
if student_name not in original_df_names_flat:
for org in orgs:
data = calculate(org, data)
result = None # May fail to get assigned if error in imported_module
try:
result = imported_module.execute(data) # here's the line where exception happens
except Exception as e:
print(f'{e}') # probably better to log the exception
return result
else:
return data
I guess an exception can occur in 2 places. So try this. It covers your exception line and the other possibility. So your program should keep running.
Secondly I have adjusted the indentation of the second try clause so the loop processes all data in orgs. To return all results I have added a list 'results'.
if student_name not in original_df_names_flat:
results = []
for org in orgs:
try:
data = calculate(org, data)
except Exception as e:
print(str(e))
try:
result = imported_module.execute(data) # here's the line where exception happens
results.append(result)
except Exception as e:
print(str(e))
return results
else:
return data
the below solution took care of the problem:
if student_name not in original_df_names_flat:
for org in orgs:
data = calculate(org, data)
try:
result = imported_module.execute(data) # here's the line where exception happens
except exception as e:
print ("exception happened", e)
pass
return data
return result
else:
return data
the above solution took care of the problem

How to properly handle multiple Runtime errors?

Program description:
Program accepts a file name and a segment, consisting of two numbers (each divided by one space). Then it outputs all lines from existing file where their indicies lie within the given segment.
My solution:
import sys
try:
par = input("Input (<file> <low border of the segment> <high border of the segment>): ").split(' ')
print(17 * '-')
f = par[0]
f_lines = [line.strip("\n") for line in f if line != "\n"]
length = len(f_lines)
if (par == ''):
raise RuntimeError('Error: undefined')
if (par[2] == None) or (par[2] == ''):
raise RuntimeError('Error: segment is limited')
if ((par[1] and par[2]) == None) or ((par[1] and par[2]) == ''):
raise RuntimeError('Error: segment undefined')
if (int(par[2]) >= length):
raise RuntimeError('Error: segment can not be greater than length the amount of lines')
if (par[1] == ''):
a = 0
if (par[2] == ''):
b = 0
segment = [int(par[1]), (int(par[2]) + 1)]
with open(par[0]) as f:
data = f.read().splitlines()
for k in range(segment[0], segment[1]):
print(data[k])
except (FileNotFoundError, IOError, NameError):
print('[!] Error: your input is incorrect. The file may be missing or something else. \n[?] For further information see full error logs: \n',sys.exc_info())
except RuntimeError as e:
print(e)
Problem:
When I try running my program in different ways to test each of my Runtime errors I always get this message:
Traceback (most recent call last):
File "C:\Users\1\Desktop\IT\pycharm\sem_2.py", line 10, in <module>
if (par[2] == None) or (par[2] == ''):
IndexError: list index out of range
I cannot wrap my head around how can I properly handle multiple Runtime errors so they would display as a text message. I haven't found any solution to my question anywhere online, so I'm trying to ask here.
I will appreciate any help, thanks in advance.
Your code would catch FileNotFoundError, IOError, NameError and RuntimeError but what is actually thrown is IndexError and that is not handled.
You may want to add IndexError it to the first except block:
except (FileNotFoundError, IOError, NameError, IndexError):
print('[!] Error: input incorrect!') # ^^^^^^^^^^^^
or perhaps add another except block if you want a custom message for IndexError:
except (FileNotFoundError, IOError, NameError):
print('[!] Error: input incorrect!')
except IndexError:
print('[!] Error: IndexError just happened!')
By the way, the following will always be False because the code in parentheses will resolve to a bool first, which can either be True or False and these are obviously never equal to '' or None:
((par[1] and par[2]) == None) or ((par[1] and par[2]) == '')
You may way want to rewrite it to:
(par[1] is None and par[2] is None) or (par[1] == '' and par[2] == '')

Error in try/except construction [duplicate]

This question already has an answer here:
Python try except else invalid syntax?
(1 answer)
Closed 6 years ago.
Im just sitting for 10 minutes staring at a simple piece of code, which I have copied from a guide and I can't understand why I am getting an error.
def transformation(x):
date_format = "%d/%m/%Y"
try:
a = dt.date(int(x[6:10]), int(x[3:5]), int(x[0:2]))
else:
a = dt.datetime.strptime(x, date_format)
finally:
return a
File "<ipython-input-91-f1f6fe70d542>", line 5
else:
^
SyntaxError: invalid syntax
Maybe this is just me... Whats wrong?
After adding except:
def transformation(x):
date_format = "%d/%m/%Y"
try:
a = dt.date(int(x[6:10]), int(x[3:5]), int(x[0:2]))
except pass
else:
a = dt.datetime.strptime(x, date_format)
finally:
return a
File "<ipython-input-93-c2285c857574>", line 5
except pass
^
SyntaxError: invalid syntax
You need an except clause to use else:
The try ... except statement has an optional else clause, which, when
present, must follow all except clauses
[Emphasis mine]
I just saw it from the python document page, so I'm just gonna quote what it says to you:
The try ... except statement has an optional else clause, which, when present, must follow all except clauses. It is useful for code that must be executed if the try clause does not raise an exception. For example:
for arg in sys.argv[1:]:
try:
f = open(arg, 'r')
except IOError:
print('cannot open', arg)
else:
print(arg, 'has', len(f.readlines()), 'lines')
f.close()

Error when the Email formencode validator

I wanted to create an IDN-aware formencode validator to use in one of my projects. I used a portion of code from the Django project (http://code.djangoproject.com/svn/django/trunk/django/core/validators.py) to do that, but there must be a trivial error in my code I can't find :
class Email(formencode.validators.Email):
def _to_python(self, value, state):
try:
return super(Email, self)._to_python(value, state)
except formencode.Invalid as e:
# Trivial case failed. Try for possible IDN domain-part
print 'heywo !'
if value and u'#' in value:
parts = value.split(u'#')
try:
parts[-1] = parts[-1].encode('idna')
except UnicodeError:
raise e
try:
super(Email, self)._to_python(u'#'.join(parts), state)
except formencode.Invalid as ex:
raise ex
return value
else:
raise e
When I try to validate an email with an IDN domain (ex: test#wääl.de), the Invalid exception raised by the first call is thrown, and the portion of code after the first except is never executed ('heywo !' is never printed).
There is an example :
>>> from test.lib.validators import Email
>>> Email().to_python(u'test#zääz.de')
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python2.6/dist-packages/FormEncode-1.2.3dev-py2.6.egg/formencode /api.py", line 416, in to_python
vp(value, state)
File "/usr/local/lib/python2.6/dist-packages/FormEncode-1.2.3dev-py2.6.egg/formencode /validators.py", line 1352, in validate_python
value, state)
Invalid: The domain portion of the email address is invalid (the portion after the #: z\xe4\xe4z.de)
What did I do wrong ?
Thanks.
Okay, found the answer. I was overloading _to_python instead of validate_python. The class now looks like :
class Email(formencode.validators.Email):
def validate_python(self, value, state):
try:
super(Email, self).validate_python(value, state)
except formencode.Invalid as e:
# Trivial case failed. Try for possible IDN domain-part
if value and u'#' in value:
parts = value.split(u'#')
try:
parts[-1] = parts[-1].encode('idna')
except UnicodeError:
raise e
try:
super(Email, self).validate_python(u'#'.join(parts), state)
except formencode.Invalid as ex:
raise ex
else:
raise e
It's working perfectly :)

Categories

Resources