scheduler.configure() parameters for SQLAlchemyJobStore

1,253 views
Skip to first unread message

Sangeeth Saravanaraj

unread,
Feb 7, 2013, 2:49:59 PM2/7/13
to apsch...@googlegroups.com
I was trying to come up with a configure string equivalent to the following lines (which can be passed to scheduler.configure() after creating a scheduler instance):

__MYSQL_url = 'mysql://root:<password>@localhost/jobstore'

scheduler = Scheduler(standalone=True)
scheduler.add_jobstore(SQLAlchemyJobStore(url=__MYSQL_url), 'default')

I referred http://packages.python.org/APScheduler/#job-stores and came up with the following for SQLAlchemyJobStore (and also referred files in examples and tests directories): The following are the instruction found in the above url to create a job store and its input (like file, path, db, etc)

jobstores.X.class        Class of the jobstore named X (specified as module.name:classname)
jobstores.X.Y            Constructor option Y of jobstore X

To find out jobstores.X.Y, I looked into the SQLAlchemyJobStore class and came up with the following options:
Option #1: (engine)
__configure = { 'apscheduler.standalone': True,
                'apscheduler.jobstores.sqlalchemy_store.class': 'apscheduler.jobstores.sqlalchemy_store:SQLAlchemyJobStore',
                'apscheduler.jobstores.sqlalchemy_store.engine': create_engine(__MYSQL_url)}
scheduler = Scheduler()
scheduler.configure(__configure)

Option #2: (url)
__configure = { 'apscheduler.standalone': True,
                'apscheduler.jobstores.sqlalchemy_store.class': 'apscheduler.jobstores.sqlalchemy_store:SQLAlchemyJobStore',
                'apscheduler.jobstores.sqlalchemy_store.url': __MYSQL_url}
scheduler = Scheduler()
scheduler.configure(__configure)

Sadly none of them are working. So my questions are as follows:

#1. What is the equivalent of jobstores.X.Y for SQLAlchemyJobStore that should be used in the configure()?
#2. How do we make a particular job store as a __default__ job store in the scheduler configure()
#3. The database name goes in the url but how should we mention the table name? 

Thank you,

Sangeeth

Alex Grönholm

unread,
Feb 7, 2013, 11:41:03 PM2/7/13
to apsch...@googlegroups.com
07.02.2013 21:49, Sangeeth Saravanaraj kirjoitti:
I was trying to come up with a configure string equivalent to the following lines (which can be passed to scheduler.configure() after creating a scheduler instance):

__MYSQL_url = 'mysql://root:<password>@localhost/jobstore'

scheduler = Scheduler(standalone=True)
scheduler.add_jobstore(SQLAlchemyJobStore(url=__MYSQL_url), 'default')

I referred http://packages.python.org/APScheduler/#job-stores and came up with the following for SQLAlchemyJobStore (and also referred files in examples and tests directories): The following are the instruction found in the above url to create a job store and its input (like file, path, db, etc)

jobstores.X.class        Class of the jobstore named X (specified as module.name:classname)
jobstores.X.Y            Constructor option Y of jobstore X

To find out jobstores.X.Y, I looked into the SQLAlchemyJobStore class and came up with the following options:
Option #1: (engine)
__configure = { 'apscheduler.standalone': True,
                'apscheduler.jobstores.sqlalchemy_store.class': 'apscheduler.jobstores.sqlalchemy_store:SQLAlchemyJobStore',
                'apscheduler.jobstores.sqlalchemy_store.engine': create_engine(__MYSQL_url)}
scheduler = Scheduler()
scheduler.configure(__configure)

Option #2: (url)
__configure = { 'apscheduler.standalone': True,
                'apscheduler.jobstores.sqlalchemy_store.class': 'apscheduler.jobstores.sqlalchemy_store:SQLAlchemyJobStore',
                'apscheduler.jobstores.sqlalchemy_store.url': __MYSQL_url}
scheduler = Scheduler()
scheduler.configure(__configure)

Sadly none of them are working. So my questions are as follows:

#1. What is the equivalent of jobstores.X.Y for SQLAlchemyJobStore that should be used in the configure()?
X is the name of the job store, Y is the constructor keyword argument.

#2. How do we make a particular job store as a __default__ job store in the scheduler configure()?
Name your store "default" instead of "sqlalchemy_jobstore".

#3. The database name goes in the url but how should we mention the table name?
apscheduler.jobstores.default.tablename: 'whatever'

Thank you,

Sangeeth
--
You received this message because you are subscribed to the Google Groups "APScheduler" group.
To unsubscribe from this group and stop receiving emails from it, send an email to apscheduler...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Sangeeth Saravanaraj

unread,
Feb 8, 2013, 11:34:38 PM2/8/13
to apsch...@googlegroups.com
X is the name of the job store:  sqlalchemy_store
Y is the constructor keyword argument: Looking at the constructor of SQLAlchemyJobStore __init__(), I tried 'engine' and 'url' arguments.

So as per the above instruction, the following lines should configure SQLAlchemyJobStore for my url. But for some reason, both of the following lines are not throwing any exceptions but there are no entries created in the table (the default table 'apscheduler_jobs' itself is not created) but the jobs are scheduled and triggered. I guess the SQLAlchemyJobStore gets configured to the Scheduler but they are not being used as default job store because the following lines by no means mentions that this job store should be assigned to the alias 'default' when adding a job sore. So any job that is scheduled, goes to the default job store (I guess RAMJobStore - correct? - please look at the python-console section of the output)     

'apscheduler.jobstores.sqlalchemy_store.engine': create_engine(__MYSQL_url)}
'apscheduler.jobstores.sqlalchemy_store.url': __MYSQL_url}


<code>
from sqlalchemy import *
from apscheduler.jobstores.sqlalchemy_store import SQLAlchemyJobStore
from apscheduler.scheduler import Scheduler
from datetime import datetime, timedelta
import time

import logging

logging.basicConfig(filename='/tmp/log', level=logging.DEBUG,
        format='[%(asctime)s]: %(levelname)s : %(message)s')

def alarm(time):
    print('Alarm! This alarm was scheduled at %s.' % time)

__MYSQL_url = 'mysql://root:<password>@localhost/jobstore'
__configure = { 'apscheduler.standalone': True,
                'apscheduler.jobstores.sqlalchemy_store.class': 'apscheduler.jobstores.sqlalchemy_store:SQLAlchemyJobStore',
                'apscheduler.jobstores.sqlalchemy_store.url': __MYSQL_url}

if __name__ == '__main__':
    #scheduler = Scheduler(standalone=True)
    #scheduler.add_jobstore(SQLAlchemyJobStore(url=_dbURL), 'default')
    scheduler = Scheduler()
    scheduler.configure(__configure)

    alarm_time = datetime.now() + timedelta(seconds=10)
    scheduler.add_date_job(alarm, alarm_time, name='alarm1', args=[datetime.now()])
    print 'alarms added: ', alarm_time

    alarm_time = datetime.now() + timedelta(seconds=15)
    scheduler.add_date_job(alarm, alarm_time, name='alarm2', args=[datetime.now()])
    print 'alarms added: ', alarm_time

    alarm_time = datetime.now() + timedelta(seconds=20)
    scheduler.add_date_job(alarm, alarm_time, name='alarm3', args=[datetime.now()])
    print 'alarms added: ', alarm_time

    try:
        scheduler.start()
    except (KeyboardInterrupt, SystemExit):
        pass
  
</code>

<log>
[2013-02-09 09:49:13,105]: INFO : Started thread pool with 0 core threads and 20 maximum threads
[2013-02-09 09:49:13,105]: INFO : Started thread pool with 0 core threads and 20 maximum threads
[2013-02-09 09:49:13,106]: INFO : Adding job tentatively -- it will be properly scheduled when the scheduler starts
[2013-02-09 09:49:13,106]: INFO : Adding job tentatively -- it will be properly scheduled when the scheduler starts
[2013-02-09 09:49:13,106]: INFO : Adding job tentatively -- it will be properly scheduled when the scheduler starts
[2013-02-09 09:49:13,107]: INFO : Added job "alarm1 (trigger: date[2013-02-09 09:49:23.106090], next run at: 2013-02-09 09:49:23.106090)" to job store "default"
[2013-02-09 09:49:13,107]: INFO : Added job "alarm2 (trigger: date[2013-02-09 09:49:28.106566], next run at: 2013-02-09 09:49:28.106566)" to job store "default"
[2013-02-09 09:49:13,107]: INFO : Added job "alarm3 (trigger: date[2013-02-09 09:49:33.106760], next run at: 2013-02-09 09:49:33.106760)" to job store "default"
[2013-02-09 09:49:13,107]: INFO : Scheduler started
[2013-02-09 09:49:13,107]: DEBUG : Looking for jobs to run
[2013-02-09 09:49:13,107]: DEBUG : Next wakeup is due at 2013-02-09 09:49:23.106090 (in 9.998263 seconds)
[2013-02-09 09:49:23,106]: DEBUG : Looking for jobs to run
[2013-02-09 09:49:23,107]: DEBUG : Started worker thread
[2013-02-09 09:49:23,107]: INFO : Removed job "alarm1 (trigger: date[2013-02-09 09:49:23.106090], next run at: None)"
[2013-02-09 09:49:23,108]: DEBUG : Next wakeup is due at 2013-02-09 09:49:28.106566 (in 4.999706 seconds)
[2013-02-09 09:49:23,107]: INFO : Running job "alarm1 (trigger: date[2013-02-09 09:49:23.106090], next run at: None)" (scheduled at 2013-02-09 09:49:23.106090)
[2013-02-09 09:49:23,108]: INFO : Job "alarm1 (trigger: date[2013-02-09 09:49:23.106090], next run at: None)" executed successfully
[2013-02-09 09:49:24,109]: DEBUG : Exiting worker thread
[2013-02-09 09:49:28,108]: DEBUG : Looking for jobs to run
[2013-02-09 09:49:28,109]: DEBUG : Started worker thread
[2013-02-09 09:49:28,109]: INFO : Running job "alarm2 (trigger: date[2013-02-09 09:49:28.106566], next run at: 2013-02-09 09:49:28.106566)" (scheduled at 2013-02-09 09:49:28.106566)
[2013-02-09 09:49:28,110]: INFO : Job "alarm2 (trigger: date[2013-02-09 09:49:28.106566], next run at: 2013-02-09 09:49:28.106566)" executed successfully
[2013-02-09 09:49:28,110]: INFO : Removed job "alarm2 (trigger: date[2013-02-09 09:49:28.106566], next run at: None)"
[2013-02-09 09:49:28,110]: DEBUG : Next wakeup is due at 2013-02-09 09:49:33.106760 (in 4.997728 seconds)
[2013-02-09 09:49:29,110]: DEBUG : Exiting worker thread
[2013-02-09 09:49:33,109]: DEBUG : Looking for jobs to run
[2013-02-09 09:49:33,109]: DEBUG : Started worker thread
[2013-02-09 09:49:33,110]: INFO : Removed job "alarm3 (trigger: date[2013-02-09 09:49:33.106760], next run at: None)"
[2013-02-09 09:49:33,110]: INFO : Running job "alarm3 (trigger: date[2013-02-09 09:49:33.106760], next run at: None)" (scheduled at 2013-02-09 09:49:33.106760)
[2013-02-09 09:49:33,110]: DEBUG : No jobs left; shutting down scheduler
[2013-02-09 09:49:33,111]: INFO : Job "alarm3 (trigger: date[2013-02-09 09:49:33.106760], next run at: None)" executed successfully
[2013-02-09 09:49:33,111]: INFO : Scheduler has been shut down
[2013-02-09 09:49:33,112]: INFO : Shutting down thread pool
[2013-02-09 09:49:33,113]: DEBUG : Exiting worker thread
</log>

<console>
$ python sqlalchemy_test0.py 
alarms added:  2013-02-09 09:49:23.106090
alarms added:  2013-02-09 09:49:28.106566
alarms added:  2013-02-09 09:49:33.106760
Alarm! This alarm was scheduled at 2013-02-09 09:49:13.106117.
Alarm! This alarm was scheduled at 2013-02-09 09:49:13.106585.
Alarm! This alarm was scheduled at 2013-02-09 09:49:13.106778.
</console>

<db>
mysql> 
mysql> use jobstore
Database changed
mysql> show tables;
Empty set (0.00 sec)

mysql> 
</db>

<python-console> 
[copy-paste the snippet in the <code> section and check the job store that has been configured by the __configure string]
>>> scheduler._jobstores
{'default': <RAMJobStore>}
>>> 
</python-console>

Re-iterating the problem statement: 
I want to add a SQLAlchemyJobStore job store for 'mysql://root:<password>@localhost/jobstore' and I want to make this job store as a default (alias) job store (whenever a job is scheduled, it should by default go to this SQLAlchemyJobStore job store). I also want to override the default value for the table (apscheduler_jobs) to my user defined table name. 

All the above mentioned parameters should be sent to the Scheduler.configure() function as a dictionary before we start the scheduler using Scheduler.start()

Thank you,

Sangeeth

Alex Grönholm

unread,
Feb 9, 2013, 12:32:32 AM2/9/13
to apsch...@googlegroups.com
Did you read my answers to questions #2 and #3? The documentation is quite clear on how to do this.
Why do you still insist on naming your job store "sqlalchemy_jobstore"?

Sangeeth Saravanaraj

unread,
Feb 9, 2013, 1:46:24 AM2/9/13
to apsch...@googlegroups.com
I have added some logs to the Scheduler class and found that the configure() is looking for a string ".jobstore" and not ".jobstores" in the dictionary that we pass as an argument. Silly me! Now, I changed the configure string to the following and got it working as expected.

__configure = { 'apscheduler.standalone': True,
                'apscheduler.jobstore.default.class': 'apscheduler.jobstores.sqlalchemy_store:SQLAlchemyJobStore',
                'apscheduler.jobstore.default.url': __MYSQL_url,
                'apscheduler.jobstore.default.tablename': 'MyJobs'}

Thank you,

Sangeeth

 


Alex Grönholm

unread,
Feb 9, 2013, 1:50:17 AM2/9/13
to apsch...@googlegroups.com
09.02.2013 08:46, Sangeeth Saravanaraj kirjoitti:
I have added some logs to the Scheduler class and found that the configure() is looking for a string ".jobstore" and not ".jobstores" in the dictionary that we pass as an argument. Silly me! Now, I changed the configure string to the following and got it working as expected.
Thank you for pointing this out. I have corrected the documentation accordingly.

Neilen Marais

unread,
Sep 26, 2013, 5:37:35 PM9/26/13
to apsch...@googlegroups.com
Hi,


On Saturday, 9 February 2013 08:50:17 UTC+2, Alex Grönholm wrote:
09.02.2013 08:46, Sangeeth Saravanaraj kirjoitti:
I have added some logs to the Scheduler class and found that the configure() is looking for a string ".jobstore" and not ".jobstores" in the dictionary that we pass as an argument. Silly me! Now, I changed the configure string to the following and got it working as expected.
Thank you for pointing this out. I have corrected the documentation accordingly.

This caused me some head-scratching since the documentation at http://pythonhosted.org/APScheduler/#scheduler-configuration-options still says '.jobstores' and  not '.jobstore'. Is that an oversight, or are you waiting for a new release before updating that site?

Thanks
Neilen

Alex Grönholm

unread,
Sep 27, 2013, 6:29:02 AM9/27/13
to apsch...@googlegroups.com
27.09.2013 00:37, Neilen Marais kirjoitti:
Hi,

On Saturday, 9 February 2013 08:50:17 UTC+2, Alex Grönholm wrote:
09.02.2013 08:46, Sangeeth Saravanaraj kirjoitti:
I have added some logs to the Scheduler class and found that the configure() is looking for a string ".jobstore" and not ".jobstores" in the dictionary that we pass as an argument. Silly me! Now, I changed the configure string to the following and got it working as expected.
Thank you for pointing this out. I have corrected the documentation accordingly.

This caused me some head-scratching since the documentation at http://pythonhosted.org/APScheduler/#scheduler-configuration-options still says '.jobstores' and  not '.jobstore'. Is that an oversight, or are you waiting for a new release before updating that site?
The official documentation hasn't been there since I switched to ReadTheDocs. PYPI being what it is, it won't allow me to delete the documentation from pythonhosted or even let me link the documentation to the correct address. I've opened a ticket for this at the PYPI bug tracker but so far it's just been collecting dust :(
Reply all
Reply to author
Forward
0 new messages