sandman2 icon indicating copy to clipboard operation
sandman2 copied to clipboard

running multiple sandman2 apps under a single wsgi

Open thatcher opened this issue 7 years ago • 4 comments

Hi Jeff. We have many legacy databases we are trying to do some data extraction on. We initially set up our approach using a single db/wsgi.py which does something like:

import os
import sys

app_dir = os.path.abspath(os.path.dirname(__file__))
project_dir = os.path.abspath(os.path.join(app_dir, '..' ))

activate_this = "%s/_env/bin/activate_this.py" % app_dir
execfile(activate_this, dict(__file__=activate_this))
sys.path.insert(0, project_dir)

from werkzeug.wsgi import DispatcherMiddleware

from foo import app as foo_app
from foo.services.goop import app as goop _db
from foo.services.blah import app as blah_db

application = DispatcherMiddleware(foo_app, {
    '/goop ': goop_db,
    '/blah ': blah_db
})

in foo/services/goop.py and foo/services/blah.py we have

app = sandman2.get_app(
    driver_uri, #driver_uri unique to each file
    read_only=True
)

where the idea is we can hit paths like:

  • /foo/ -> general stuff for our project
  • /foo/goop/admin/ -> sandman2 admin for goop database
  • /foo/blah/admin/ -> sandman2 admin for blah database

The problem is we see the table for both databases in both admin panels! And we get a lot of errors like: SAWarning: This declarative base already contains a class with the same class name and module name...

The gist appears to be that there can only be one call to sandman2.get_app per wsgi as there is some class level state being set/stored and thus duplicating the information across the admin pages.

Thoughts? Is there just a better way we are missing or does it boil down to a separate wsgi per database?

Thanks! Thatcher

thatcher avatar Aug 03 '16 16:08 thatcher

This can be done, but I need to see how much refactoring is necessary. In the meantime, you're free to use a separate wsgi server per database and all will work as expected (though I realize that's not ideal).

jeffknupp avatar Aug 03 '16 19:08 jeffknupp

Thanks Jeff. Appreciated.

thatcher avatar Aug 05 '16 14:08 thatcher

Jeff, thanks a lot, really appreciate you looking at this! (A colleague of @thatcher )

ptrourke avatar Aug 05 '16 20:08 ptrourke

The Flask-Admin instance retains some internal state when it is initiated, in some cases when running the unit tests and instantiating Flask-Admin outside of the application factory I have encountered an error claiming I have registered duplicate views. (I had a link somewhere to the Flask-Admin issue tracker that explained this but can't find it now.)

The Flask-SQLAlchemy instance use the "DATABASE_URL" value set upon the application. This is read whenever one invokes it directly SQLALchemy(app) or initiates an instance, data=SQLAlchemy(), later on database.init(app). My understanding is that flask supports multiple database connections through binds, but I have not used this personally. Perhaps setting this might allow you to map multiple databases in one instance but I think the Flask-Admin issue might still bite you.

Carelvd avatar Nov 05 '19 21:11 Carelvd