MySQLdb error local variable referenced before assignment (different than usual)

北慕城南 提交于 2019-12-24 16:35:17

问题


I am attempting to add some data to MySQL database via a loop that iterates through the API that returns a JSON file. I am using Python and MySQLdb module.

For some reason I am getting the infamous UnboundLocalError. I looked at the other scenarios when this problem occurred and that have already been answered on StackOverflow but nothing resonated with me and I couldn't apply it directly to this problem.

Here's my code:

def request(API_KEY, URL, ch_no):
    url = URL + ch_no + '/request'
    request = requests.get(url, auth=(API_KEY, ''))
    data_dict = request.json()
    data_dict_json_dumps = json.dumps(data_dict)
    data = json.loads(data_dict_json_dumps) 

    try:
        for item in data['items']:
            return (item['tag'], item['created_on'], item['delivered_on'], item['satisfied_on'], item['status'], item['particulars']['description'], item['persons_entitled'][0]['name'])   
    except KeyError:
        pass

    try:
        description = item['particulars']['description']
    except KeyError:
        description = None
    try:
        persons_entitled = item['persons_entitled'][0]['name']
    except KeyError:
        persons_entitled = None 

    try:
        cursor.execute("""INSERT INTO companies_and_charges_tmp (tags, company_id, created, delivered, satisfied, status, description, persons_entitled) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)""", (item.get('tag'), ch_no, item.get('created_on'), item.get('delivered_on'), item.get('satisfied_on'), item.get('status'), description, persons_entitled))
    db.commit()

    finally: 
        time.sleep(0.5)

    del data

for ch_no in ch_nos:
    charges_request(API_KEY, URL, ch_no)

And here's the full error:

Traceback (most recent call last):
  File "test2.py", line 58, in <module>
    charges_request(API_KEY, URL, ch_no)
  File "test2.py", line 49, in charges_request
    cursor.execute("""INSERT INTO companies_and_charges_tmp (etags, company_id, created, delivered, satisfied, status, description, persons_entitled) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)""", (item.get('etag'), ch_no, item.get('created_on'), item.get('delivered_on'), item.get('satisfied_on'), item.get('status'), description, persons_entitled))
UnboundLocalError: local variable 'item' referenced before assignment

回答1:


The issue is that item is only assigned when you enter the for loop

for item in data['items']:
    ...

If data['items'] is empty, you never do so, and item remains unassigned.




回答2:


Since this script iterates through the loop and some of the returned variables are NULL python then (rightfully so) throws the UnboundLocalError as the variable isn't there/hasn't been declared.

I attempted to handle this problem by using:

except KeyError:

However, the errors we are dealing with here aren't only KeyErrors but also UnboundLocalErrors, so handling only one of the errors wasn't effective.

I modified the script in the following way (mind you this works in Python 2.7 I am not sure if the same syntax is possible in Python 3):

try:
    description = item['particulars']['description']
except (UnboundLocalError, KeyError):
    #declaring the description as None if not there so MySQL/Python don't throw an error
    description = None

and then when adding data to MySQL database I am also using the error handler and passing if there is one:

try:
    cursor.execute("""INSERT INTO companies_and_charges_tmp (etags, company_id, created, delivered, satisfied, status, description, persons_entitled) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)""", (item.get('etag'), ch_no, item.get('created_on'), item.get('delivered_on'), item.get('satisfied_on'), item.get('status'), description, persons_entitled))
    db.commit()
except UnboundLocalError:
     pass


来源:https://stackoverflow.com/questions/37377695/mysqldb-error-local-variable-referenced-before-assignment-different-than-usual

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!