How do I handle mySQL exceptions in Python? - python

I would like to ask how do I handle MySQL exceptions in Python. Basically, my program asks for the number of descriptions they would like to enter and I have an if statement to check that the number they have entered does not exceed 10. However, the column in my database called "Description" only allows 100 characters. Thus, the total number of chars entered by the user cannot exceed 100 chars, however, I cannot catch the exception. I have looked at multiple online resources such as importing "mysql.connector" and tried catching the DataError exception but it is still not working. I also tried specifying the exact exception but it still gives the same error when I try to test entering characters more than 100. Does anyone know any possible ways I can address this?
My end goal is to print out the cause of the error to the user and inform them that they cannot enter more than 100 characters and prevent the program from stopping abruptly. Thank you.
Below are some snapshots of my code and the exception I am trying to catch.
My Code
Exception encountered and trying to catch

The exception you need to catch is in the last line of your "Exception encountered and trying to catch" image.
The exception is of type "mysql.connector.error.DataError".
In your first image you are catching "mysql.connector.DataError".
You are missing an "error." in between.

Your code seems to be incomplete, so I am assuming this is what you are looking for. From the MySQL Connector/Python Developer Guide, section 10.12.2 errors.Error Exception, I propose the following solution:
import mysql.connector
...
while True:
try:
number_of_description = int(input("Enter the number of descriptions you would like to give the item: "))
except ValueError:
print("You cannot enter a non-number value. Please try again.")
except mysql.connector.Error as err:
if err.errno == 1406:
print('DataError: This exception is raised when there were problems with the data.')
continue

Related

Python Django - delaying ValidationError until for loop completes

I'm working on an app that simulates a social media site. I currently have a form where users can enter in their friends' emails so they can be invited to join the app.
Let's say we have a user who enters in three email addresses to the email form which are then saved as a list of strings:
emails_to_invite = ["jen#website.com", "mike#website.com", "joe#website.com"]
In the database, we already have a list of users who have already been invited to the site:
current_users = ["jen#website.com", "mike#website.com", "dan#website.com", "kim#website.com"]
So we have two users who have already been invited: jen#website.com and mike#website.com.
I'm trying to write some code that returns a ValidationError and can list both matched users in the message. Here's what I have so far:
for email in emails_to_invite:
if email in current_users:
raise forms.ValidationError(f"{email} is already in the database.")
Here's how I want this error to display:
jen#website.com is already in the database.
mike#website.com is already in the database.
But right now, the error only displays the first email:
jen#website.com is already in the database.
I also need mike#website.com to display too. It appears that the for loop stops once it recognizes one match, but I need it to keep going until it recognizes all matches. Can anyone offer some suggestions?
If you don't want an Exception in a code-block to halt your execution (and hide further exceptions, as you've found), put the susceptible code in a a try/except block to handle the error as you see fit.
To later raise the exception, consider using something like:
raised_exceptions = []
<loop that might raise exceptions>
try:
<loop that might raise exceptions>
except Exception as e:
raised_exceptions.append(e)
<do something with the exceptions you saved>
That being said, IMO you shouldn't be using exceptions in this way - consider returning a series of lists, one per possible outcome, instead: email sent and already invited (and/or joined user)

Python try / except / else loop does both the try and else actions

I'm running a Python script to post a Tweet if the length is short enough with an exception for errors and an else statement for messages that are too long.
When I run this, it posts the Tweet and still gives the Tweet too long message. Any idea why that is happening and how to make it work as intended?
if len(tweet_text) <= (280-6):
try:
twitter = Twython(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET)
twitter.update_status(status=tweet_text)
except TwythonError as error:
print(error)
else:
print("Tweet too Long. Please try again.")
The first string is checking the length of the tweet. Move the else four spaces back. Because try/except construction can be try/except/else construction
From the docs:
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. (emphasis added)
Spaces/Tabs matter in Python.
What your snippet says in common English
is "Try to post the tweet, unless there's an error, then print the error. If there's not an error, print 'Tweet too long. Please try again.'"
What you want is:
if len(tweet_text) <= (280-6):
try:
twitter = Twython(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET)
twitter.update_status(status=tweet_text)
except TwythonError as error:
print(error)
else:
print("Tweet too Long. Please try again.")

Pandas/Python how to skip errors and goto the next line of code?

Please mind you, I'm new to Pandas/Python and I don't know what I'm doing.
I'm working with CSV files and I basically filter currencies.
Every other day, the exported CSV file may contain or not contain certain currencies.
I have several such cells of codes--
AUDdf = df.loc[df['Currency'] == 'AUD']
AUDtable = pd.pivot_table(AUDdf,index=["Username"],values=["Amount"],aggfunc=np.sum)
AUDtable.loc['AUD Amounts Rejected Grand Total'] = (AUDdf['Amount'].sum())
AUDdesc = AUDdf['Amount'].describe()
When the CSV doesn't contain AUD, I get ValueError: cannot set a frame with no defined columns.
What I'd like to produce is a function or an if statement or a loop that checks if the column contains AUD, and if it does, it runs the above code, and if it doesn't, it simply skips it and proceeds to the next line of code for the next currency.
Any idea how I can accomplish this?
Thanks in advance.
This can be done in 2 ways:
You can create a try and except statement, this will try and look for the given currency and if a ValueError occurs it will skip and move on:
try:
AUDdf = df.loc[df['Currency'] == 'AUD']
AUDtable = pd.pivot_table(AUDdf,index=["Username"],values["Amount"],aggfunc=np.sum)
AUDtable.loc['AUD Amounts Rejected Grand Total'] = (AUDdf['Amount'].sum())
AUDdesc = AUDdf['Amount'].describe()
except ValueError:
pass
You can create an if statement which looks for the currencies presence first:
currency_set = set(list(df['Currency'].values))
if 'AUD' in currency_set:
AUDdf = df.loc[df['Currency'] == 'AUD']
AUDtable = pd.pivot_table(AUDdf,index=["Username"],values=["Amount"],aggfunc=np.sum)
AUDtable.loc['AUD Amounts Rejected Grand Total'] = (AUDdf['Amount'].sum())
AUDdesc = AUDdf['Amount'].describe()
1.Worst way to skip over the error/exception:
try:
<Your Code>
except:
pass
The above is probably the worst way because you want to know when an exception occur. using generic Except statements is bad practice because you want to avoid "catch em all" code. You want to be catching exceptions that you know how to handle. You want to know what specific exception occurred and you need to handle them on an exception-by-exception basis. Writing Generic except statements leads to missed bugs and tends to mislead while running the code to test.
Slightly worse way to handle the exception:
try:
<Your Code>
except Exception as e:
<Some code to handle an exception>
Still not optimal as it is still generic handling
Average way to handle it for your case:
try:
<Your Code>
except ValueError:
<Some code to handle this exception>
Other suggestion - Much Better Ways to deal with this:
1.You can get a set of the available columns at run time and aggregate based on if 'AUD' is in the list.
2.Clean your data set
You can use try and except where
try:
#your code here
except:
#some print statement
pass

How to handle 2 different errors in Python 3, both of which are ValueError

I have a list of twitter usernames that I use to get tweets. During the process, I face 2 main errors:
CRITICAL:root:twint.get:User:'user'
raise ValueError("Cannot find twitter account with name = " + self.config.Username)
ValueError: Cannot find twitter account with name = blablabla
CRITICAL:root:twint.get:User:'data'
raise ValueError("Cannot find twitter account with name = " + self.config.Username)
ValueError: Cannot find twitter account with name = blablabla
The first one happens when the username is incorrect and I don't mind passing the error. However, the second one I believe is due to connection timeout or something similar, because whenever I get that error, I stop the script for 3-4 minutes and continue and it goes on as usual.
Therefore, I want to catch the 2nd error and handle it with sleep(). The problem is, if I do this it will sleep through incorrect username error as well and that's a waste of time:
try:
some code
except ValueError:
sleep(200)
How can I make it sleep only if the 2nd error happens?

Python: Make HTTP Errors (500) Not Stop Script

This is the basic part of my code that I need help with. Note I learned python like last week. I don't understand try and exceptions and I know that what I need for this, so if anyone could help that would be great.
url = 'http://google.com/{0}/{1}'.format(variable, variable1)
site = urllib.request.urlopen(url)
That's not the real website but you get the idea. Now I'm running a loop over 5 times per item, then running around 20 different items. So it goes to say
google.com/spiders/(runs 5 times with diff types of spiders)
google.com/dogs/(runs 5 times with diff types of dogs)etc.
Now the 2nd variable is the same on like 90% of the items I'm looping over, but 1 or 2 of them have some of the "types" but not others. So I get an http error 500 because that site doesn't exist. How do I make it basically skip that. Its not something else, I know error 500 isn't the right error I believe, but I know the pages for those items don't exist. So how do I set this up so that it just skips that one if it gets any error.
You can use a try/except block in your loop, like:
try:
url = 'http://google.com/{0}/{1}'.format(variable, variable1)
site = urllib.request.urlopen(url)
except Exception, ex:
print "ERROR - " + str(ex)
You can also just catch specific exceptions - the above code would catch any exception (such as a bug in your code, not a network error)
See here for more: https://wiki.python.org/moin/HandlingExceptions

Categories

Resources