librelist archives

« back to archive

Sharing objects in multi-module applications

Sharing objects in multi-module applications

From:
Date:
2013-07-09 @ 10:37
Hello,

I have some trouble figuring out the best way of sharing (redis, postgresql)
object instances in my multi-module flask application. The only examples I can
find are single-module applications, like here:

http://flask.pocoo.org/docs/extensiondev/

[...]
db = SQLite3(app)

@app.route('/')
def show_all():
    cur = db.connection.cursor()
    cur.execute(...)


So how do you get to the db instance and its methods/properties if your
application consists of multiple modules?

- import the instances from the main app module:
  from app import db

- assign to a "shared" module and import from that module in view modules:
  shared.db = db = SQLite3(app)

- tie instances directly to the app(lication) object:
  app.db = db = SQLite3(app)


Other options?

For me, these layout and sharing between modules situations are the most
confusing part about Flask. Thanks for any help!


PS: I am aware of threading and am using redis/psycopg connection pools.

Re: [flask] Sharing objects in multi-module applications

From:
Adam Patterson
Date:
2013-07-09 @ 21:42
# extensions.py
from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()

# app.py
from flask import Flask
from extensions import db

def create_app():
    app = Flask(__name__)
    db.init_app(app)
    return app

then just use app = create_app()

Then you can import from extensions from anywhere.

This is an overly simplified example - read the rest here
http://flask.pocoo.org/docs/patterns/appfactories/



On Tue, Jul 9, 2013 at 3:37 AM, <wouter-flask@publica.duodecim.org> wrote:

>
> Hello,
>
> I have some trouble figuring out the best way of sharing (redis,
> postgresql)
> object instances in my multi-module flask application. The only examples I
> can
> find are single-module applications, like here:
>
> http://flask.pocoo.org/docs/extensiondev/
>
> [...]
> db = SQLite3(app)
>
> @app.route('/')
> def show_all():
>     cur = db.connection.cursor()
>     cur.execute(...)
>
>
> So how do you get to the db instance and its methods/properties if your
> application consists of multiple modules?
>
> - import the instances from the main app module:
>   from app import db
>
> - assign to a "shared" module and import from that module in view modules:
>   shared.db = db = SQLite3(app)
>
> - tie instances directly to the app(lication) object:
>   app.db = db = SQLite3(app)
>
>
> Other options?
>
> For me, these layout and sharing between modules situations are the most
> confusing part about Flask. Thanks for any help!
>
>
> PS: I am aware of threading and am using redis/psycopg connection pools.
>
>

Re: [flask] Sharing objects in multi-module applications

From:
Date:
2013-07-10 @ 11:00
> # extensions.py
> from flask.ext.sqlalchemy import SQLAlchemy
> db = SQLAlchemy()
>
> # app.py
> from flask import Flask
> from extensions import db
>
> def create_app():
>     app = Flask(__name__)
>     db.init_app(app)
>     return app
>
> then just use app = create_app()
>
> Then you can import from extensions from anywhere.
>
> This is an overly simplified example - read the rest here
> http://flask.pocoo.org/docs/patterns/appfactories/
>

Interesting. I hadn't thought of using factory functions for this purpose. So
I would basically create the objects in a shared module beforehand and attach
them later, at application creation time; whereas now I assign them to a
shared module after application creation but before adding views.

I guess there's always some chicken-and-egg consideration as to which should
happen first...

Thanks!

Re: [flask] Sharing objects in multi-module applications

From:
Philippe Ndiaye
Date:
2013-07-10 @ 09:22
Personally, i like to use the second solution, i have a "common" package
where i add all the code used in the whole application (database model,
Jinja extensions ...)
So i guess the this one would be cool in your case.

- assign to a "shared" module and import from that module in view modules:
  shared.db = db = SQLite3(app)


On Tue, Jul 9, 2013 at 12:37 PM, <wouter-flask@publica.duodecim.org> wrote:

>
> Hello,
>
> I have some trouble figuring out the best way of sharing (redis,
> postgresql)
> object instances in my multi-module flask application. The only examples I
> can
> find are single-module applications, like here:
>
> http://flask.pocoo.org/docs/extensiondev/
>
> [...]
> db = SQLite3(app)
>
> @app.route('/')
> def show_all():
>     cur = db.connection.cursor()
>     cur.execute(...)
>
>
> So how do you get to the db instance and its methods/properties if your
> application consists of multiple modules?
>
> - import the instances from the main app module:
>   from app import db
>
> - assign to a "shared" module and import from that module in view modules:
>   shared.db = db = SQLite3(app)
>
> - tie instances directly to the app(lication) object:
>   app.db = db = SQLite3(app)
>
>
> Other options?
>
> For me, these layout and sharing between modules situations are the most
> confusing part about Flask. Thanks for any help!
>
>
> PS: I am aware of threading and am using redis/psycopg connection pools.
>
>


-- 
*Philippe Thécou NDIAYE*
Etudiant à SUPINFO Lyon
Sysadmin Linux & Développeur Python

Re: [flask] Sharing objects in multi-module applications

From:
Date:
2013-07-10 @ 11:02
> Personally, i like to use the second solution, i have a "common" package
> where i add all the code used in the whole application (database model,
> Jinja extensions ...)
> So i guess the this one would be cool in your case.
>
> - assign to a "shared" module and import from that module in view modules:
>   shared.db = db = SQLite3(app)
>

Are you using application factories for this or just assign the instances
after the application has already been created – i.e. which one you create
first, the application or the other objects?

Thanks!

Re: [flask] Sharing objects in multi-module applications

From:
Philippe Ndiaye
Date:
2013-07-10 @ 13:12
I create the application first, like that :
    *app = Flask(__name__)

*then i bind the database object after (using SQLAlchemy by exemple):
    *app.config[YOUR KEY] = ...
*
*    db = SQLAlchemy(app)

*
By doing like this, the application, its configuration and the database
object are declared only once, and *models are declared in a shared
module*(by example, if you have a frontend app and backend app, you
don't want to
define models in both). It permit you to avoid Circular Import too.


On Wed, Jul 10, 2013 at 1:02 PM, <wouter-flask@publica.duodecim.org> wrote:

> > Personally, i like to use the second solution, i have a "common" package
> > where i add all the code used in the whole application (database model,
> > Jinja extensions ...)
> > So i guess the this one would be cool in your case.
> >
> > - assign to a "shared" module and import from that module in view
> modules:
> >   shared.db = db = SQLite3(app)
> >
>
> Are you using application factories for this or just assign the instances
> after the application has already been created – i.e. which one you create
> first, the application or the other objects?
>
> Thanks!
>
>


-- 
*Philippe Thécou NDIAYE*
Etudiant à SUPINFO Lyon
Sysadmin Linux & Développeur Python