11

I have a Flask application with which I'd like to use SQLAlchemy Core (i.e. I explicitly do not want to use an ORM), similarly to this "fourth way" described in the Flask doc:

http://flask.pocoo.org/docs/patterns/sqlalchemy/#sql-abstraction-layer

I'd like to know what would be the recommended pattern in terms of:

  1. How to connect to my database (can I simply store a connection instance in the g.db variable, in before_request?)

  2. How to perform reflection to retrieve the structure of my existing database (if possible, I'd like to avoid having to explicitly create any "model/table classes")

1 Answer 1

10
  1. Correct: You would create a connection once per thread and access it using a threadlocal variable. As usual, SQLAlchemy has thought of this use-case and provided you with a pattern: Using the Threadlocal Execution Strategy

     db = create_engine('mysql://localhost/test', strategy='threadlocal')
     db.execute('SELECT * FROM some_table')
    

Note: If I am not mistaken, the example seems to mix up the names db and engine (which should be db as well, I think).

I think you can safely disregard the Note posted in the documentation as this is explicitly what you want. As long as each transaction scope is linked to a thread (as is with the usual flask setup), you are safe to use this. Just don't start messing with threadless stuff (but flask chokes on that anyway).

  1. Reflection is pretty easy as described in Reflecting Database Objects. Since you don't want to create all the tables manually, SQLAlchemy offers a nice way, too: Reflecting All Tables at Once

     meta = MetaData()
     meta.reflect(bind=someengine)
     users_table = meta.tables['users']
     addresses_table = meta.tables['addresses']
    

I suggest you check that complete chapter concerning reflection.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks, that's useful. Would you know where to put this code? This answer provides a possible way, which seems to work with what I want to do.
Actually, I would just do it during application startup. This way, once your application runs you know everything is up and don't have a first request that takes longer because of reflection. Thus: Define it at the import level. Then either manually assign your tables like above or only access the required one during a request like in the answer your linked.
I'm a bit confused about step 1. In the OP cjauvin suggested to get a connection from the engine and store it on the g object. i.e. @app.before_request def before_request(): g.db = engine.connect() and use that throughout the request. Is this the same as creating the engine using the 'threadlocal' strategy? Or do you need to do both?
Basically yes, mostly because flask heavily relies on the assumption that you have a thread per request. If you were to alter this and have multiple requests per thread (in whichever way you achieve this) you'd want to prefer something that doesn't rely on threadlocal variables (i.e. events, callbacks, etc.).
I don't think you need to create the engine using threadlocal mode. The g object is already threadlocal. Inside before_request you can create a new connection and add it to g. Inside your route you can execute g.conn.execute(select([Foo])). Then in after_request you can issue g.conn.close(). Do you agree with this?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.