Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blueprints and Extensions and SQLAlchemy #289

Open
mitsuhiko opened this issue Jul 30, 2011 · 7 comments
Open

Blueprints and Extensions and SQLAlchemy #289

mitsuhiko opened this issue Jul 30, 2011 · 7 comments
Labels

Comments

@mitsuhiko
Copy link
Member

@mitsuhiko mitsuhiko commented Jul 30, 2011

We do not encourage people to create more than one database connection and to connect to databases in arbitrary extensions. The obvious exception are extensions whose sole purpose is to connect to databases. Dependency resolving is done by the developer. Eg:

app = Flask(__name__)
db = SQLAlchemy(app)
something = SomethingElse(app, db)

The problem comes with blueprints. If SomethingElse wants to define models it has to do that at a local scope where it has the reference to the db. Assuming it provides blueprints, how does the blueprint's views and other code get to the models? The sad truth is that if you make up blueprints on the fly the views in that blueprint don't know how to reference it.

@mrjoes

This comment has been minimized.

Copy link
Contributor

@mrjoes mrjoes commented Jul 30, 2011

It depends from the use case.

I have following assumptions:

  1. Application might want to access blueprint models
  2. There can be more than one instance of the blueprint, so there can be multiple instances of the same model mapped to different or same database table(s) (using prefixed table name, etc)
  3. Blueprints don't know how they're going to be used in the application - all parameters are passed in object creation time
  4. Which brings to the point - blueprints should always dynamicly create their models based on the input parameters to the constructor

For #1, snippet can look like:
something.MyModel.query.all()

@benallard

This comment has been minimized.

Copy link

@benallard benallard commented Nov 23, 2011

I came across this issue with my bugLink project (http://buglink.readthedocs.org/), where the basic app knows about the relationship changeset <-> issue, and extensions to the app should provide release <-> build <-> changeset ( <-> issue).

My understanding of this is that Blueprint are intended to extend the views. If you need to extend the model, you need to define something like a YellowPrint. As the model is highly coupled with the controller, YellowPrint could also have some mechanism in place to extend your controller. But there is no point in extending the controller if you don't make use of the extension provided. Here we come back to the views. Which brings us to the GreenPrint if you need to extend the views and the model.

@jfinkels

This comment has been minimized.

Copy link
Contributor

@jfinkels jfinkels commented Apr 5, 2012

I don't know if this is exactly the situation you are describing, but I have something that looks like this in Flask-Restless. Check out http://readthedocs.org/docs/flask-restless/en/latest/quickstart.html

@jack-nie

This comment has been minimized.

Copy link

@jack-nie jack-nie commented Jul 27, 2013

Nice work!

@untitaker untitaker modified the milestone: 0.9 Oct 7, 2014
@untitaker untitaker removed the 0.8 label Oct 7, 2014
@untitaker untitaker modified the milestones: 0.9, 1.0, 0.11 Apr 25, 2015
@davidism davidism self-assigned this Oct 30, 2015
@davidism

This comment has been minimized.

Copy link
Member

@davidism davidism commented Oct 30, 2015

There are a few solutions I've seen, depending on the use case:

  • Inject dependencies and explicitly generate the views. This use is a good use case for class based views. During init_app, the extension generates the models and passes them to as_view. This is similar to what @jfinkels mentions.
  • Provide abstract bases for the models, and expect the user to subclass them and use callbacks to set proxies. Flask-Login does this with UserMixin, login_manager.user_loader, and current_user. This is useful when
  • Set properties on the extension instance, then pull them from current_app.extensions['my_ext'].MyModel in views. I don't have an example off the top of my head, but this is a similar concept to Flask-Login's login_manager.anonymous_user.

I'll work on some short examples for each of these solutions to add to the docs on extensions.

@davidism davidism modified the milestones: 1.0, 0.11 Jun 1, 2016
@davidism davidism removed the feedback label Apr 19, 2017
@kennethreitz

This comment has been minimized.

Copy link
Contributor

@kennethreitz kennethreitz commented May 25, 2017

Closing as this issue is OLD.

@kennethreitz

This comment has been minimized.

Copy link
Contributor

@kennethreitz kennethreitz commented May 25, 2017

keeping open as this seems important

@davidism davidism removed their assignment Feb 28, 2018
@davidism davidism modified the milestones: 1.0, 1.1 Mar 8, 2018
@davidism davidism removed this from the 1.1.0 milestone May 30, 2019
@jab jab added the save-for-sprint label May 30, 2019
@pallets pallets deleted a comment from MajidHeydari Dec 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
10 participants
You can’t perform that action at this time.