Re: SQLAlchemy integration in Flask

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Monday, December 6, 2021 6:36:56 PM CET Aurelien Bompard wrote:
> Hey folks!
> 
> I'd like to open a can of worms: SQLAlchemy integration in Flask. It's a
> long read but I hope you'll like it. I try not to be on the ranty side.
> 
> First, some context: we have been plagued by tech debt for a very long
> time, maybe more than other development projects because web tech has
> evolved very quickly in the past 15 years (after the big flatline of "I
> need to be IE6-compatible", but I digress), and also because we're a small
> team maintaining a ton of apps.
> 
> In the past, we've had to switch web frameworks a couple of times.
> Turbogears 1, then Turbogears 2, then Flask, but we also have apps in
> CherryPy (to this day!) and Pyramid (and somewhat Django although we're not
> maintaining them). As a result we've grown very suspicious of framework
> integration because that means more work when we (inevitably) have to
> migrate to a different framework. I think it's partly why we chose Flask at
> the time: it's a minimalist framework, therefore there will be less
> integration bits to migrate away from. I don't agree entirely with this
> point of view but I think the standardization has done us a lot of good.
> 
> We've also standardized on SQLAlchemy for our DB, which is great. But we
> haven't standardized on how to integrate the two. There's an integration
> library called Flask-SQLAlchemy, but our apps don't use it (to my
> knowledge).

FTR, Copr uses Flask-SQLAlchemy.

Pavel

> I think that the reason is that Flask-SQLAlchmemy makes your models unusable
> without Flask, and that triggers our "what if the framework goes away" PTSD.
> Here's an example of what models look like with Flask-SQLAlchemy:
> 
> from flask import Flaskfrom flask_sqlalchemy import SQLAlchemy
> 
> app = Flask(__name__)
> app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
> db = SQLAlchemy(app)
> class User(db.Model):
>     id = db.Column(db.Integer, primary_key=True)
>     username = db.Column(db.String(80), unique=True, nullable=False
> 
> As you can see, the User class inherits from db.Model, something that the
> Flask-SQLAlchemy extension provides. Same for the Column and the DB types.
> I do understand why it would make us flinch to "tie" our models to the web
> framework, even indirectly. (that said, if we want to migrate those models
> from Flask-SQLAlchemy to native SQLAlchemy, it would be so trivial that
> plain sed can handle it)
> 
> So we've tried to do the SQLAlchemy integration in Flask ourselves. This
> has two downsides:
> - it's not as easy as it looks, especially when migrations and Alembic come
> into play
> - we end up with many slightly different integrations, written by different
> people or even the same person at different points in time.
> Ironically, our attempt at avoiding tech debt has caused us more tech debt.
> 
> Flask-SQLAlchemy has however some pretty strong points:
> - it's widely used and of good quality
> - it's maintained by the same people who maintain Flask (although the same
> cannot be said of Flask-Migrate, the Alembic integration)
> - it gives us some shortcuts very common in web apps, like get_or_404 or
> pagination support, that we also had to write ourselves with differing
> implementations.
> 
> But if we don't want to go this route, I've extracted a lightweight way of
> integrating SQLAlchemy in Flask that leaves the models usable without
> Flask. I think it's a reasonable concern to separate entirely the models
> from the web app framework, so I'm not advocating for Flask-SQLAlchemy
> here. I'm advocating against each app having its own integration.
> 
> On top of that, while I don't see us moving away from Flask anytime soon, I
> do see a reason why we would want to look at other web frameworks in the
> near future, and that reason is async support. Flask 2.x has grown support
> for async views, but it's not as good
> <https://flask.palletsprojects.com/en/2.0.x/async-await/#when-to-use-quart-instead>
> as other async-native frameworks such as FastAPI or Starlette, and
> extensions are unlikely to support it. That said, using async with
> SQLAlchemy requires doing away with quite a few convenience features of the
> ORM, such as implicit queries on model attributes, so moving to an async
> framework would require us to rewrite all the database access layer anyway.
> Maybe this is not a good example after all.
> 
> Anyway, this long email is about finding a common ground for SQLAlchemy
> integration in Flask, while taking into account our difficult experiences
> with webframewoks in the past, but not being locked in them. Is there
> something that I misrepresented here? Do you have opinions? Preferences?
> 
> Thanks!
> 
> Aurélien
> 



_______________________________________________
infrastructure mailing list -- infrastructure@xxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to infrastructure-leave@xxxxxxxxxxxxxxxxxxxxxxx
Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: https://lists.fedoraproject.org/archives/list/infrastructure@xxxxxxxxxxxxxxxxxxxxxxx
Do not reply to spam on the list, report it: https://pagure.io/fedora-infrastructure




[Index of Archives]     [Fedora Development]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]

  Powered by Linux