Search code examples
pythontimerpymssql

Python polling MSSQL at set interval


I have a need to poll a MSSQL database to watch the status of a running job. I want to run a status check every X seconds to see if the status=done. I am trying to use the threading module. I have tested the threading module with some simple print statements and it seems to work, but when I try inside my pymssql script it does not.

def watcher_query(cursor):
    print 'Watching'
    return cursor.execute(""" select *
                              from some_table' """)
def is_it_done(row):
    if row['status'] == 'done':
        return row['the_id'], True
    else:
        return row['the_id'], False

def d(cur):
    watcher_query(cur)
    for row in cur:
        return is_it_done(row)[1]
    threading.Timer(100, d).start()

def job_watch(server):
    with pymssql.connect(server_info) as conn:
        with conn.cursor(as_dict=True) as cur:
            is_done = false
            while is_done:
                is_done = d(cur)

No matter what I set the threading.Timer to I see the 'Watching' statement print constantly. Is there a better way to set the polling timer perhaps?

I have also tried to use Twisted to set up a basic function which makes a function call every X sec until some condition is met. I haven't tried it with MSSQL yet though.


Solution

  • The way your code is written it doesn't seems to be in a working order:

    1. It doesn't compile because of is_done = false,

    2. If fixed to is_done = False, it skips the loop straight away,

    3. Even if the loop is fixed in some reasonable way you never get to call threading.Timer(100, d).start() and don't examine any other rows as you return from d straight away after examining the first row using return is_it_done(row)[1]

    It doesn't matter what the actual timed worker method does, prints to console or checks the database, should work just the same with the same timer.

    What about something like this:

    import threading
    
    
    def is_it_done():
        # get some dummy predictable results
        if not hasattr(is_it_done, 'results'):
            is_it_done.results = iter([False] * 3)
        return next(is_it_done.results, True)
    
    
    def job_watch():
        is_done = False
    
        def d():
            is_done = is_it_done()
            print('is_done: {}'.format(is_done))
            timer = threading.Timer(3, d).start()
    
        d()
    
    
    job_watch()