2

I'm trying to scale up my first Flask app and am not understanding the structure needed to use a pymongo db in multiple modules. For example, here is my new structure:

run.py
app/
├── __init__.py
├── forms.py
├── static/
├── templates/
└── views/
    ├── __init__.py
    ├── bookmarklet.py
    ├── main.py
    └── user.py

Prior to trying to scale this, I had this at the top of my single views.py file:

from flask.ext.pymongo import PyMongo
mongo = PyMongo(app)
with app.app_context():
    mongo.db.user.ensure_index("email", unique=True)

The goal is to be able to use this mongo instance in all of the view modules as well as the forms.py module. I've tried these two things:

  1. Put the above snippet in the app/__init__.py file, but can't seem to make it accessible to any other modules. I tried doing this: app.db = mongo.db (but it wasn't available downstream)
  2. Put the above snippet into each module that needs it, but then I get the error that there are multiple mongo instances with the same prefix.

Where should this initialization go in order to make it accessible everywhere in the app?

EDIT

It sounds like I'm doing it right but there is something else going on. I'm posting my more complete code and error.

app/__init__.py

from flask import Flask

app = Flask(__name__)
from app.views import main

app.config.update(
    DEBUG = True,
    SECRET_KEY = "not telling",
    WTF_CSRF_ENABLED = False,
)

app.jinja_env.add_extension('pyjade.ext.jinja.PyJadeExtension')

from flask.ext.pymongo import PyMongo
mongo = PyMongo(app)
with app.app_context():
    mongo.db.user.ensure_index("email", unique=True)

app/views/main.py

from app import app
from flask import render_template, redirect, request, flash, url_for
from flask.ext.jsonpify import jsonify
from app.forms import *

from app import *
print mongo

Error:

(venv)imac: me$ ./run.py 
Traceback (most recent call last):
  File "./run.py", line 4, in <module>
    from app import app
  File "/Users/me/Dropbox/development/test/app/__init__.py", line 4, in <module>
    from app.views import main
  File "/Users/me/Dropbox/development/test/app/views/main.py", line 9, in <module>
    print mongo
NameError: name 'mongo' is not defined
Scott
  • 3,204
  • 3
  • 31
  • 41

2 Answers2

2

Put that snippet in app/__init__.py. If you want to access it in forms.py, for instance, try:

...
from app import *
# then you can use mongo here
print mongo
...

If you want to access it in user.py, for instance, try the same code above.

Check if this works for you. If not, show me the error message and I will think about solution two.

Stephen Lin
  • 4,852
  • 1
  • 13
  • 26
  • I appreciate you taking a second look. I've posted code and error above. – Scott Dec 29 '14 at 15:15
  • I have this feeling that it is something to do with the usage of `app`. At the beginning of the file I have to do `from app import app`. Then later, if I reference `app`, how does it know which to use? I've also tried it without `from app import *` and just used `print app.mongo` to no avail. – Scott Dec 29 '14 at 15:23
2

SOLVED

The mistake in my __init__.py file was that I was importing my views to early. You have to do that at the end!

WRONG

from flask import Flask

app = Flask(__name__)
from app.views import main # <- TOO EARLY

app.config.update(
    DEBUG = True,
    SECRET_KEY = "not telling",
    WTF_CSRF_ENABLED = False,
)

app.jinja_env.add_extension('pyjade.ext.jinja.PyJadeExtension')

from flask.ext.pymongo import PyMongo
mongo = PyMongo(app)
with app.app_context():
    mongo.db.user.ensure_index("email", unique=True)

RIGHT

from flask import Flask
from flask.ext.pymongo import PyMongo

app = Flask(__name__)

mongo = PyMongo(app)
with app.app_context():
    mongo.db.user.ensure_index("email", unique=True)

app.config.update(
    DEBUG = True,
    SECRET_KEY = "not telling",
    WTF_CSRF_ENABLED = False,
)

app.jinja_env.add_extension('pyjade.ext.jinja.PyJadeExtension')

# AT THE BOTTOM!
from app.views import main
Scott
  • 3,204
  • 3
  • 31
  • 41