6

I'm attempting to use the "application factory" pattern from flask, but I seem to have a chicken-and-egg problem with my models. http://flask.pocoo.org/docs/patterns/appfactories/

I am importing my views in the create_app function, which imports my models. So, I don't have a config in the app when my models are being defined. This is usually fine, using the bind keys, I can set up models to connect to different dbs.

However, in this case, I have two sets of models, one from the default database, and another set on another db connection - and I'd like to cross-db join. I know that the usual method is to add

__table_args__ = { 'schema' : 'other_db_name' }

to my "other db" models.

But...depending on the config, the 'other_db_name' may be different.

So, now I have models being defined that require the schema name from the config, but with no schema from the config to put in the class definition. I also may simply be missing something in flask I wasn't aware of.

(Side note - an easy fix for this is to configure Sqlalchemy to always output the schema name in the query, no matter what - but I can't seem to find a setting for this.)

If anyone has any input on this, I'd be very much obliged. Thanks!

1 Answer 1

5

Never tried this myself, but you can probably force __table_args__ to have lazy evaluation by making it a declared_attr.

from sqlalchemy.ext.declarative import declared_attr

class MyModel(MySQLSettings, MyOtherMixin, Base):
    __tablename__='my_model'

    @declared_attr
    def __table_args__(cls):
        return { 'schema': current_app.config['OTHER_DB_NAME'] }
Sign up to request clarification or add additional context in comments.

4 Comments

This is a great idea, but doesn't seem to work. It looks like the declarative base still looks for table_args on definition, and I'm still not in an application context when I get there. Thanks for the reply!
You should probably investigate why this does not work. The SQLAlchemy documentation mentions the use of declared_attr for __table_args__ a few times. See here, for example.
Yes, I agree with you that I should be able to have that function called for table_args - but I still don't yet have the config set (by the application context) by the time that declared_attr is called to set the table args. So - I don't think it's lazily evaluated to the point beyond the flask app starting up...
I would think you need to initialize app.config before you initialize app.db. Is that the order you are using?

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.