SQLAlchemy and flask w/blueprints: engine/sessionmaker lifetime
In the past months I've written half a dozen of little flask/sqlalchemy applications, and it looks like I'll keep going. They're mostly independent intranet tools giving views and evaluations of data in various company databases. I have one blueprint with basically the company logo, a style sheet and some common views (login/logout). So a typical app follows this boilerplate pattern:
if (production_environment):
engine_1 = create_engine(uri_1)
engine_2 = create_engine(uri_2)
engine_3 = create_engine(uri_3)
else: # offline the intranet
engine_1 = create_engine(devel_server)
# etc.
Session_1 = sessionmaker(...)
Session_2 = sessionmaker(...)
Session_3 = sessionmaker(...)
app = Flask("some_app")
app.register_blueprint(company_layout)
# this is needed for the company blueprint template to display the
# title of the app in the top title bar
app.config['TITLE'] = "Some App"
@app.route('/')
def index():
db1 = Session_1
db2 = Session_2
... you get the gist.
Now that's a lot of boilerplate code. At first I thought to factor out all this config and database setup stuff into a separate module with the sessionmakers and a function that would and return a fully set-up app. But that still leaves me with a lot of separate apps all of which need to be given their own entry points at the webserver/wsgi level, and also they can't link to one another in a development server.
From the flask docs I understand that the way to deal with this situation is to factor out all the little apps into individual blueprints, then create one centrally configured main app and registering all blueprints on it. I've tried it, and it works as expected. But there are a few things I either can't figure out, or seem to have figured out in a strange 'this isn't how this is meant to work' fashion.
Number one: I want the blueprint to set its own title to be displayed in the top layout template. Right now I'm using the config['TITLE'] hack to do that. Is this what a context processor is meant to be used for?
Number two: The databases. The sqlalchemy docs say that engines and sessionmaker are supposed to be set up once outside the app/request context and create/close session on a per-request level (the way I'm doing this now). This seems to contradict the flask documentation which suggests database URIs be set in the app's config (which elegantly solves the production/development distinction). However, this means that the entire database infrastructure needs to be set up and torn down on each and every request because everything happens inside the app context. Then I'd somehow need to create all engine and sessionmakers in the main app module, somehow pass them down to the blueprints, and have the blueprint make the Sessions that it needs. How do I do that? Somehow use the 'g' object? Doesn't this induce siginificant overhead?
Anyway, as you can see I'm a little stuck on the architectural side of my site and I'd appreciate anly suggestions. Thanks.
PS: I've read the app factory docs at pooco,org but couldn't make enough sense of it to decide if it helps me with my problem. I'm not using Flask-SQLAlchemy because I can't tell what it is good for. Almost all of the documentation just repeats database model design stuff from SQLAlchemy but doesn't explain any benefits of using Flask-SQLAlchemy over vanilla SQLAlchemy with scoped_session. What is seems to do is make a lot of the underlying SQLalchemy mechanics invisible in ways I don't understand.
flask sqlalchemy
add a comment |
In the past months I've written half a dozen of little flask/sqlalchemy applications, and it looks like I'll keep going. They're mostly independent intranet tools giving views and evaluations of data in various company databases. I have one blueprint with basically the company logo, a style sheet and some common views (login/logout). So a typical app follows this boilerplate pattern:
if (production_environment):
engine_1 = create_engine(uri_1)
engine_2 = create_engine(uri_2)
engine_3 = create_engine(uri_3)
else: # offline the intranet
engine_1 = create_engine(devel_server)
# etc.
Session_1 = sessionmaker(...)
Session_2 = sessionmaker(...)
Session_3 = sessionmaker(...)
app = Flask("some_app")
app.register_blueprint(company_layout)
# this is needed for the company blueprint template to display the
# title of the app in the top title bar
app.config['TITLE'] = "Some App"
@app.route('/')
def index():
db1 = Session_1
db2 = Session_2
... you get the gist.
Now that's a lot of boilerplate code. At first I thought to factor out all this config and database setup stuff into a separate module with the sessionmakers and a function that would and return a fully set-up app. But that still leaves me with a lot of separate apps all of which need to be given their own entry points at the webserver/wsgi level, and also they can't link to one another in a development server.
From the flask docs I understand that the way to deal with this situation is to factor out all the little apps into individual blueprints, then create one centrally configured main app and registering all blueprints on it. I've tried it, and it works as expected. But there are a few things I either can't figure out, or seem to have figured out in a strange 'this isn't how this is meant to work' fashion.
Number one: I want the blueprint to set its own title to be displayed in the top layout template. Right now I'm using the config['TITLE'] hack to do that. Is this what a context processor is meant to be used for?
Number two: The databases. The sqlalchemy docs say that engines and sessionmaker are supposed to be set up once outside the app/request context and create/close session on a per-request level (the way I'm doing this now). This seems to contradict the flask documentation which suggests database URIs be set in the app's config (which elegantly solves the production/development distinction). However, this means that the entire database infrastructure needs to be set up and torn down on each and every request because everything happens inside the app context. Then I'd somehow need to create all engine and sessionmakers in the main app module, somehow pass them down to the blueprints, and have the blueprint make the Sessions that it needs. How do I do that? Somehow use the 'g' object? Doesn't this induce siginificant overhead?
Anyway, as you can see I'm a little stuck on the architectural side of my site and I'd appreciate anly suggestions. Thanks.
PS: I've read the app factory docs at pooco,org but couldn't make enough sense of it to decide if it helps me with my problem. I'm not using Flask-SQLAlchemy because I can't tell what it is good for. Almost all of the documentation just repeats database model design stuff from SQLAlchemy but doesn't explain any benefits of using Flask-SQLAlchemy over vanilla SQLAlchemy with scoped_session. What is seems to do is make a lot of the underlying SQLalchemy mechanics invisible in ways I don't understand.
flask sqlalchemy
add a comment |
In the past months I've written half a dozen of little flask/sqlalchemy applications, and it looks like I'll keep going. They're mostly independent intranet tools giving views and evaluations of data in various company databases. I have one blueprint with basically the company logo, a style sheet and some common views (login/logout). So a typical app follows this boilerplate pattern:
if (production_environment):
engine_1 = create_engine(uri_1)
engine_2 = create_engine(uri_2)
engine_3 = create_engine(uri_3)
else: # offline the intranet
engine_1 = create_engine(devel_server)
# etc.
Session_1 = sessionmaker(...)
Session_2 = sessionmaker(...)
Session_3 = sessionmaker(...)
app = Flask("some_app")
app.register_blueprint(company_layout)
# this is needed for the company blueprint template to display the
# title of the app in the top title bar
app.config['TITLE'] = "Some App"
@app.route('/')
def index():
db1 = Session_1
db2 = Session_2
... you get the gist.
Now that's a lot of boilerplate code. At first I thought to factor out all this config and database setup stuff into a separate module with the sessionmakers and a function that would and return a fully set-up app. But that still leaves me with a lot of separate apps all of which need to be given their own entry points at the webserver/wsgi level, and also they can't link to one another in a development server.
From the flask docs I understand that the way to deal with this situation is to factor out all the little apps into individual blueprints, then create one centrally configured main app and registering all blueprints on it. I've tried it, and it works as expected. But there are a few things I either can't figure out, or seem to have figured out in a strange 'this isn't how this is meant to work' fashion.
Number one: I want the blueprint to set its own title to be displayed in the top layout template. Right now I'm using the config['TITLE'] hack to do that. Is this what a context processor is meant to be used for?
Number two: The databases. The sqlalchemy docs say that engines and sessionmaker are supposed to be set up once outside the app/request context and create/close session on a per-request level (the way I'm doing this now). This seems to contradict the flask documentation which suggests database URIs be set in the app's config (which elegantly solves the production/development distinction). However, this means that the entire database infrastructure needs to be set up and torn down on each and every request because everything happens inside the app context. Then I'd somehow need to create all engine and sessionmakers in the main app module, somehow pass them down to the blueprints, and have the blueprint make the Sessions that it needs. How do I do that? Somehow use the 'g' object? Doesn't this induce siginificant overhead?
Anyway, as you can see I'm a little stuck on the architectural side of my site and I'd appreciate anly suggestions. Thanks.
PS: I've read the app factory docs at pooco,org but couldn't make enough sense of it to decide if it helps me with my problem. I'm not using Flask-SQLAlchemy because I can't tell what it is good for. Almost all of the documentation just repeats database model design stuff from SQLAlchemy but doesn't explain any benefits of using Flask-SQLAlchemy over vanilla SQLAlchemy with scoped_session. What is seems to do is make a lot of the underlying SQLalchemy mechanics invisible in ways I don't understand.
flask sqlalchemy
In the past months I've written half a dozen of little flask/sqlalchemy applications, and it looks like I'll keep going. They're mostly independent intranet tools giving views and evaluations of data in various company databases. I have one blueprint with basically the company logo, a style sheet and some common views (login/logout). So a typical app follows this boilerplate pattern:
if (production_environment):
engine_1 = create_engine(uri_1)
engine_2 = create_engine(uri_2)
engine_3 = create_engine(uri_3)
else: # offline the intranet
engine_1 = create_engine(devel_server)
# etc.
Session_1 = sessionmaker(...)
Session_2 = sessionmaker(...)
Session_3 = sessionmaker(...)
app = Flask("some_app")
app.register_blueprint(company_layout)
# this is needed for the company blueprint template to display the
# title of the app in the top title bar
app.config['TITLE'] = "Some App"
@app.route('/')
def index():
db1 = Session_1
db2 = Session_2
... you get the gist.
Now that's a lot of boilerplate code. At first I thought to factor out all this config and database setup stuff into a separate module with the sessionmakers and a function that would and return a fully set-up app. But that still leaves me with a lot of separate apps all of which need to be given their own entry points at the webserver/wsgi level, and also they can't link to one another in a development server.
From the flask docs I understand that the way to deal with this situation is to factor out all the little apps into individual blueprints, then create one centrally configured main app and registering all blueprints on it. I've tried it, and it works as expected. But there are a few things I either can't figure out, or seem to have figured out in a strange 'this isn't how this is meant to work' fashion.
Number one: I want the blueprint to set its own title to be displayed in the top layout template. Right now I'm using the config['TITLE'] hack to do that. Is this what a context processor is meant to be used for?
Number two: The databases. The sqlalchemy docs say that engines and sessionmaker are supposed to be set up once outside the app/request context and create/close session on a per-request level (the way I'm doing this now). This seems to contradict the flask documentation which suggests database URIs be set in the app's config (which elegantly solves the production/development distinction). However, this means that the entire database infrastructure needs to be set up and torn down on each and every request because everything happens inside the app context. Then I'd somehow need to create all engine and sessionmakers in the main app module, somehow pass them down to the blueprints, and have the blueprint make the Sessions that it needs. How do I do that? Somehow use the 'g' object? Doesn't this induce siginificant overhead?
Anyway, as you can see I'm a little stuck on the architectural side of my site and I'd appreciate anly suggestions. Thanks.
PS: I've read the app factory docs at pooco,org but couldn't make enough sense of it to decide if it helps me with my problem. I'm not using Flask-SQLAlchemy because I can't tell what it is good for. Almost all of the documentation just repeats database model design stuff from SQLAlchemy but doesn't explain any benefits of using Flask-SQLAlchemy over vanilla SQLAlchemy with scoped_session. What is seems to do is make a lot of the underlying SQLalchemy mechanics invisible in ways I don't understand.
flask sqlalchemy
flask sqlalchemy
asked Nov 23 '18 at 9:13
musburmusbur
847
847
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53443641%2fsqlalchemy-and-flask-w-blueprints-engine-sessionmaker-lifetime%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53443641%2fsqlalchemy-and-flask-w-blueprints-engine-sessionmaker-lifetime%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown