add_setup, add_data_func, and database-backed configuration

3 views
Skip to first unread message

David Bronke

unread,
Jan 15, 2010, 12:08:35 PM1/15/10
to glash...@googlegroups.com
I've recently discovered Glashammer, and I'm now in the process of rewriting one of my current Django projects (EPIC; a Trac/Redmine replacement) over to Glashammer.

I want to use a database-backed configuration system for pretty much everything except database location and session cookie name. I need a lot of things to be 'project'-dependent and editable through the page at runtime, and the extra flexibility of database-backed configuration will make that possible.

My issue comes with where to place some of the initialization code. Currently, I have the following setup code in my main app: (I'm using Elixir with SQLAlchemy, which is why create_all() has no arguments)
def setup_data(app):
    setup_all()
    create_all()

    Configuration.setValue('global', 'templatesDir', 'templates')
 
    # Data directories
    templatesDir = Configuration.getPath('global', 'templatesDir', default='templates')
    app.add_template_searchpath(templatesDir)

    mediaDir = Configuration.getPath('global', 'mediaDir', default='media')
    app.add_shared('main', mediaDir)

def setup(app):
    # Configuration file variables
    app.add_config_var('data_dir', str, DEFAULT_DATA_DIRECTORY)
    app.add_config_var('databaseUrl', str, 'sqlite:///' + join(DEFAULT_DATA_DIRECTORY, '/test.db'))
    databaseUrl = app.conf['databaseUrl']

    # Database setup
    metadata.bind = databaseUrl
    app.add_setup(setup_sqlalchdb, databaseUrl, metadata)

    Configuration.baseDir = app.conf['data_dir']

    app.add_setup(setup_auth, True)
    app.add_data_func(setup_data)

The separation between 'setup' and 'data' callables isn't entirely clear to me. In the documentation, it states about the data callables, "This is separate from the setup callables in that they are run afterwards, so we can be sure that code requiring this bundle’s initialization has been called." This doesn't make it clear which ones are run after which. What happens when there are setup callables that register both setup and data callables? For example, in the above code, will setup_auth or setup_data be called first?


Chat: AIM: FunkieMous
FacebookDeviantARTTwitter

Ali Afshar

unread,
Jan 15, 2010, 1:41:19 PM1/15/10
to glash...@googlegroups.com


2010/1/15 David Bronke <whit...@gmail.com>

I've recently discovered Glashammer, and I'm now in the process of rewriting one of my current Django projects (EPIC; a Trac/Redmine replacement) over to Glashammer.

I want to use a database-backed configuration system for pretty much everything except database location and session cookie name. I need a lot of things to be 'project'-dependent and editable through the page at runtime, and the extra flexibility of database-backed configuration will make that possible.

My issue comes with where to place some of the initialization code. Currently, I have the following setup code in my main app: (I'm using Elixir with SQLAlchemy, which is why create_all() has no arguments)
def setup_data(app):
    setup_all()
    create_all()

    Configuration.setValue('global', 'templatesDir', 'templates')
 
    # Data directories
    templatesDir = Configuration.getPath('global', 'templatesDir', default='templates')
    app.add_template_searchpath(templatesDir)

    mediaDir = Configuration.getPath('global', 'mediaDir', default='media')
    app.add_shared('main', mediaDir)

def setup(app):
    # Configuration file variables
    app.add_config_var('data_dir', str, DEFAULT_DATA_DIRECTORY)
    app.add_config_var('databaseUrl', str, 'sqlite:///' + join(DEFAULT_DATA_DIRECTORY, '/test.db'))
    databaseUrl = app.conf['databaseUrl']

    # Database setup
    metadata.bind = databaseUrl
    app.add_setup(setup_sqlalchdb, databaseUrl, metadata)

    Configuration.baseDir = app.conf['data_dir']

    app.add_setup(setup_auth, True)
    app.add_data_func(setup_data)

The separation between 'setup' and 'data' callables isn't entirely clear to me. In the documentation, it states about the data callables, "This is separate from the setup callables in that they are run afterwards, so we can be sure that code requiring this bundle’s initialization has been called." This doesn't make it clear which ones are run after which. What happens when there are setup callables that register both setup and data callables? For example, in the above code, will setup_auth or setup_data be called first?


Hi, the setup callable never actually calls the data callable, it merely registers it. I apologise for the poor explanation in the documentation. The process is like:

Main app setup is called.
    - This registers a number of bundles to be called later (setup callables)
        - Each bundle may register any number of other bundles
        - Each bundle may register any number of data callabless
    - Also registers a number of data callables to be called
    - All registered setup callables are called
    - All registered data callables are called

The reason for the two steps is that before running any data callables, we must be sure that all bundles have loaded. This is useful so that Bundle A (db library) and Bundle B (pages library) can be loaded and that B can use A to initialise data, while being 100% sure that the db library has been loaded. Otherwise, if it was all in the setup callable, the order that the bundles are loaded would become an issue, and I wanted to avoid that as much as possible.

I hope this general explanation makes more sense than the documentation.

As for using a bundle for configuration, that is a tricker issue. The problem is that in Glashammer "configuration" is a core entity, and "databasing" is a bundled entity. Core entities are loaded automatically, before bundle instances exist, so there is no state where a core entity depends on a bundle. What I would probably do in that case is to sublass glashammer.aapplication.Application to make your database layer behave as a core entity. This would give you far more control, anyway, and probably prevent you from having any discrepancies between data and setup callables, as you have indicated above.

I can help you with an example, but I think if you do take this approach for something like SQLAlchemyGlashammerApplication, it would be something useful for the core Glashammer code, as many people would want to hard-code the user of sqlalchemy for databasing.

p.s. Thanks for your interest in Glashammer! I hiope your project works out ok. Please let me know if I can help at all. A redmine clone written in Glashammer would be very useful to me, so perhaps we could collaborate on it somewhat.

Regards,

Ali
Reply all
Reply to author
Forward
0 new messages