Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Try two expressions with `try except`

I have two expressions. I need to try one expression, if it is raise an exception try another, but if the second raises an exception too - to raise the exception.

I tried this, but it is looks ugly and I am not sure it is the best way to solve this issue:

try:                                                           
    image = self.images.order_by(func.random()).limit(1)       
except:                                                        
    try:                                                       
        image = self.images.order_by(func.rand()).limit(1)     
    except ProgrammingError:                                   
        raise ProgrammingError(                                
            'The database engine must be PostgtreSQL or MySQL')

How do you do it?

like image 700
I159 Avatar asked Aug 13 '12 14:08

I159


2 Answers

Making a separate function is very helpful.

def get_random_image(self):
    for rand in func.random, func.rand:
        try:                                                           
            return self.images.order_by(rand()).limit(1)
        except ProgrammingError:                                                        
            pass
    raise ProgrammingError('This database engine is not supported')
like image 198
Oleh Prypin Avatar answered Sep 21 '22 22:09

Oleh Prypin


Use a loop:

for methname in ("random", "rand"):
    try:
        image = self.images.order_by(getattr(func, methname)()).limit(1)
        break
    except ProgrammingError:
        continue
else:
    raise ProgrammingError("The database engine must be PostgtreSQL or MySQL")

The loop's else clause is executed only if the loop terminates normally (i.e., without a break) which is why we break after doing the image assignment. If you consider this too tricksy, because the else clause is so infrequently used with for, then this would also work:

image = None
for methname in ("random", "rand"):
    try:
        image = self.images.order_by(getattr(func, methname)()).limit(1)
    except ProgrammingError:
        continue
if not image:
    raise ProgrammingError("The database engine must be PostgtreSQL or MySQL")
like image 20
kindall Avatar answered Sep 18 '22 22:09

kindall