2

I am having a problem with the python script that I am trying to automate in cron. I belive that the problem is in the mysql module not being imported when running the script through cron.

I tried different solution in the net but none of them seems to be working.

Btw, the script is running normal when executing in terminal

Here is my crontab:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:$HOME/bin
PYTHONPATH=/usr/lib/python2.7/site-packages
#MAILTO=root
# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
* * * * * /usr/bin/python /var/www/html/testlist.py > /var/log/test.log 2>&1

and here is the error generated in test.log

Traceback (most recent call last):
File "/var/www/html/testlist.py", line 106, in <module>
if  __name__ =='__main__':main()
File "/var/www/html/testlist.py", line 104, in main
get_ec2_instances('us-west-1')
File "/var/www/html/testlist.py", line 90, in get_ec2_instances
insert_metric(d[u'Timestamp'],d[u'Average'],d[u'Unit'])
File "/var/www/html/testlist.py", line 49, in insert_metric
cursor.close()
UnboundLocalError: local variable 'cursor' referenced before assignment

and here is the part of the script that causing the error:

#!/usr/bin/python
import argparse
import boto.ec2
import boto.ec2.cloudwatch
import datetime
import json
import ast
import sys
sys.path.append('/usr/lib/python2.7/site-packages')
from mysql.connector import MySQLConnection, Error
from mysql_connect import read_db_config

def insert_metric(timestamp,average,unit):
    print "Inserting now"
    query = "INSERT INTO metrics_tbl(timestamp,average,unit) " \
            "VALUES(%s,%s,%s)"
    args = (timestamp,average,unit)

    try:
        db_config = read_db_config()
        conn = MySQLConnection(**db_config)
        cursor = conn.cursor()
        cursor.execute(query, args)

        if cursor.lastrowid:
            print('last insert id', cursor.lastrowid)
        else:
            print('last insert id not found')

        conn.commit()
    except Error as error:
        print(error)

    finally:
        cursor.close()
        conn.close()

Thanks

4
  • An exception occurred in the try-suite. So cursor was not successfully defined. The error message should have been printed in /var/log/test.log. What does it say? Commented Feb 5, 2016 at 10:46
  • the error is posted above. It is about UnboundLocalError: local variable 'cursor' referenced before assignment. I am getting the same error when I simulate, removing the import mysql.connector then execute the script in shell. Commented Feb 5, 2016 at 10:51
  • What happens if you remove the try, except, finally lines, dedent the code inside and just run the code "bare"? Then you should see in test.log the traceback error message of the true originating exception. Commented Feb 5, 2016 at 10:58
  • Thank you! I got the real culprit when i remove the try, except, finally. The problem is in the mysql_connector.py. I wasn't able to defined the config file using its absolute path. Thank you @unutbu Commented Feb 5, 2016 at 11:12

1 Answer 1

1

Have you read the traceback ??? The problem is quite clear: in your finally clause, you're trying to access the name cursor while it's not yet defined.

Look at your code: you're defining cursor at the third line of the try block - so until your code reaches that point, the name cursor does not exists. Now if one of the two first statements raises and exception, you end up in the finally block, where you try to access cursor...

try:
     db_config = read_db_config()
     conn = MySQLConnection(**db_config)
     cursor = conn.cursor()
     cursor.execute(query, args)

     if cursor.lastrowid:
         print('last insert id', cursor.lastrowid)
     else:
         print('last insert id not found')

     conn.commit()
 except Error as error:
     print(error)

 finally:
     cursor.close()
     conn.close()

To solve this (first) problem, you need to either have a narrower try block and/or define cursor (and conn) before the try block.

First, extract the call to read_db_config from the try block - you don't need it here. If it fails, you'll have a traceback anyway... Then define conn and cursor to None before the try block so you don't have a NameError in the finally block, and, in the finally block, test whether cursor and conn have been opened before closing them. Also, your except clause is more than useless - it prevents you from getting the full traceback (which is invaluable for debugging), so just remove it and let the exception propagate:

conn = None
cursor = None
db_config = read_db_config()

try:
     conn = MySQLConnection(**db_config)
     cursor = conn.cursor()
     cursor.execute(query, args)
     if cursor.lastrowid:
         print('last insert id', cursor.lastrowid)
     else:
         print('last insert id not found')
     conn.commit()
finally:
    if cursor is not None:
        cursor.close()
    if conn is not None:
        conn.close()

Now you can run your code again and this time find out what's the REAL problem (which obviously has nothing to do with importing MySQLdb - else you'd get an ImportError right up from the start and your code wouldn't even be called).

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, I got the real cause of the problem. The problem is in the mysql_connector.py. I wasn't able to define the config file in the script using its absolute path. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.