Django vs. Flask for a long-term project
stackoverflow.com
stackoverflow.com
RDB managment is the biggest snorefest in all of software development. There are some times where you have to figure out some crazy select or whatever, but for the most part it's annoying, easy to break, and it takes forever. Django lets me not think about it at all (granted, I'm not writing crazy search things either).
When I started trying out Play Framework (for Scala, because I love type checking) I was absolutely shocked at the lack of an ORM. DB managment is the most boilerplate-y aspect of writing some CRUD, and Play decides not to help you with it.
Their arguments are about "control" and how somehow "SQL is the best DSL" (http://www.playframework.com/documentation/2.0.1/ScalaAnorm).
>val id: Int = SQL("insert into City(name, country) values ({name}, {country}") .on("Cambridge", "New Zealand").executeInsert()
Who could possibly think this "DSL" is 'better' than something like
>City("Cambridge","New Zealand").save()
/endrant
I really like ORMs, and django has the distinction of having the best ORM in my book. I sincerely hope Django would never be reduced to Flask, because I care a lot more about having DB management work without me ripping my hair out than having routes or being able to put everything in one file.
EDIT: for context, I don't ever have to do complicated things with databases, mainly tedious ones, which is probably why my vision of the world might be slightly different than yours.
>City("Cambridge","New Zealand").save()
I had no idea that New Zealand was a city! Can I ask how the cities of Cambridge and New Zealand are related, though? Is one like the billing city and the other the shipping city?
>City(name="Cambridge", country="New Zealand").save()
Doesn't change the point about SQL.
So now you have me going and editing tested, working code just for my personal preference and digging through code that I may or may not be authorized to view. Do you have any other best practices to share?
Besides, keyword arguments do solve the problem. Also, correctly named variables ( City(city_name,country_name).save() ) and , if need be, some comments all solve this issue.
Spoken like someone who never had to deal with recordsets of 40 different values, accessed by position, passed around various functions... ORMs can be a problem, in the sense that complex queries may be harder or impossible to express, and there can be a cost in terms of performance. Snark over keyword arguments, which are completely orthogonal to ORMs, is both rude and misplaced.
Furthermore, ORM queries a much more readable, and the OP's example is bad; Django ORM queries use keyword arguments all the time.
If you like ORM's check out SQLAlchemy, it is pretty damn awesome.
But I feel it does what a framework should : solves 95% of the cases well, and gives a backdoor for the other 5% (the "extra" query). I might be heavily influenced on the generally good experiences I had with the models too though.
Thanks for the recommendation, I'll check it out.
People that hate leaky abstractions.
People that understand that having the full power of SQL is better than a mediating layer -- as your needs get more evolved than inserting a simple row.
People that are not afraid to learn SQL, and know that it's exactly a DSL built for relational data.
People that trust an industry standard DSL more than some ad-hoc DSL built on top of it.
People that know they can reuse the very same SQL across many different contexts, from their code in multiple languages to the rdbms command line client itself, whereas code for an ORM not so much.
SQL is already a leaky abstraction over the DBMS system's particular optimizations, or haven't you heard about people rewriting queries for Postgres or Oracle because of the engine's peculiarities?
> People that understand that having the full power of SQL is better than a mediating layer -- as your needs get more evolved than inserting a simple row.
There's nothing incompatible between using SQL for that 2% of cases and an ORM for the rest
> People that are not afraid to learn SQL, and know that it's exactly a DSL built for relational data.
I don't think anyone's afraid of SQL, but I sure as hell would be afraid of maintaining hundreds of plaintext SQL queries every time I add a new column.
> People that trust an industry standard DSL more than some ad-hoc DSL built on top of it.
All SQL implementations have ad-hoc additions that are platform-specific, and most ORMs work pretty damn well.
> People that know they can reuse the very same SQL across many different contexts, from their code in multiple languages to the rdbms command line client itself, whereas code for an ORM not so much.
This is BS. I have to touch a substantially larger amount of code when refactoring SQL than when touch ORM queries.
Seriously, have you even used a decent ORM?
Which doesn't detract from my argument. Since leaky abstractions are bad why on earth would you double or triple them, building another abstraction (ORM) on the first one (SQL)?
>There's nothing incompatible between using SQL for that 2% of cases and an ORM for the rest
For serious development you'll find it's not just "2% of cases". YMMV. And again, there is something incompatible: certain ORMS make it difficult or prevent it altogether, and even if they allow it you end with a hybrid ORM/SQL codebase.
>I don't think anyone's afraid of SQL
I've met plenty of people who do. Some even think it's alien, the same way some people wouldn't touch LISP syntax with a bargepole.
>but I sure as hell would be afraid of maintaining hundreds of plaintext SQL queries every time I add a new column
If you need to do that, then you're doing it wrong.
>All SQL implementations have ad-hoc additions that are platform-specific, and most ORMs work pretty damn well.
"Pretty damn well"? As in generating slow ass queries, needing 300 pages of documentation (I'm thinking of Hibernate) for stuff you can do in 5 minutes in SQL, etc?
Here's a gem from Django's 1.6 release notes (that somebody praised its ORM in the comments above): "The Model.save() method now tries to directly UPDATE the database if the instance has a primary key value. Previously SELECT was performed to determine if UPDATE or INSERT were needed".
>This is BS. I have to touch a substantially larger amount of code when refactoring SQL than when touch ORM queries.
Have you even tried to understand what it says? You can take your SQL and use it in another language, or in the DB CLI etc. Your ORM code is tied to your original codebase. No using SQL Alchemy if you switch to Java.
>Seriously, have you even used a decent ORM?
I've used SQL Alchemy, Hibernate and Django's ORM.
Never found a decent one.
But I know that connect-the-dots, Visual Basic style developers swear by them.
I see nothing wrong with this; almost all tables have automatic sequences for PK insertion. The proper idiom for creating a new instances is the model.objects.create() method, and save() supports the force_insert argument. This is a valid optimization and reflects the use case of people who are using the framework.
I've been developing web apps for over half a decade, some of them pretty massive, most for regular businesses. The number of times I have needed to drop to SQL I can count with my hands outside of the limited domain of reporting.
If you need to use SQL for regular old CRUD behavior, either your models are not being properly normalized or you're using a shitty ORM, and neither SQLAlchemy nor Django are bad ORMs. If your problem is that your domain object is spread across 15 tables and you actually need all those joins, there's always methods that invoke the necessary SQL and return the encapsulated objects, but like I said, you have bigger problems there than worrying about your query abstractions.
I'm using one called Activate (http://activate-framework.org/) in a few of my latest projects and it's really simplified things. There's also Squeryl, ReactiveMongo, Slick...
Django is ideal for the freelancer or developer that needs great tools available at their disposal for quick and high-quality development.
Flask is ideal for the large system and application where many components are expected to be built bottom-up and extra flexibility is needed.
The intersection point for both use cases goes to the point where you're having several people working on a project full time, and at that point you'll likely have much more important things to be concerned about.
The best thing about Django is that all apps respect the app structure, middlewares, URL dispatch mechanism, and template tags, so it is trivial to create detachable, modular applications and use them for your own project.
I can download one of dozens of applications that improve upon the provided functionality and the chances of there being an incompatibility are minor. Installing apps is trivial, migrating all your new applications' schema is consistent.
People truly underestimate just how imporant it is to have a framework with no surprises and consistency. This is something that Flask does not provide and weighs heavily when you need external functionality.
In any case, there are several extremely good 3rd-party asset pipelines
As such, the killer app of Django is Django.
Saying, "Oh, I could do that with X" is a bullshit statement. You could build an Django-like admin in Fortran.
Yes, you can hack together an admin tool in any templating system, using any ORM, or even raw SQL if you like. It's all just CRUD operations, and provided sufficient/consistent abstraction you can make it work, for your own project, without any troubles. You could, with sufficient work, even create an admin as simple as the register command.
This is the power the ecosystem at play though. When I snag a Django app to add to me project, it comes with an admin. I don't have to cobble one together.
I can replace the Django admin with an api-compatible alternative like Grappelli or Suit, and 98% of all the applications out there for Django will go right on working.
So the admin is not a killer app (per se) but is an example of how Django itself IS a killer app, because the admin is powered by it, and the community enabled by it.
The admin depends on uniform URL conventions driven by the framework and the URL reversion mechanism to get object URLs.
The CRUD DB functionality depends on the models being compatiable with the Django ORM interface, as well as the forms and the interations between the ORM and forms which allows for things like ModelForms.
The admin has its own set of important template tags to render information depending on the context, and that allows for consisten overriding and enhancing of functionality.
The imporant thing is that, even though all those components are decoupled, they were made in mind to interact flawlessly, and share idioms and interfaces that allow them to work together in ways that that more decoupled frameworks do not.
Finally, while there is nothing special about each component per se, most people seriously exaggerate the shortcomings of each, and there is no component in Django that is plainly bad, something that I have personally seen in pretty much every other framework I have worked with. Consistency is important.
http://flask-admin.readthedocs.org/en/latest/index.html
I haven't used it, but looking at the quickstart, you gain a lot of flexibility in exchange for a bit of boilerplate. As I haven't done any Django in a long time, I cannot comment on how complete it is, but it shows that you can absolutely achieve this kind of functionality in a framework with a tiny core.
Unfortunately for me, the most memorable part of the experience was repeatedly calculating how many times I could have coded the exact same solution in PHP in the time it took me to finish a Flask project.
Oh, and don't even get me started on deployment.
This is compounded by the fact that there's a much greater amount of service-style applications (Single-page web or mobile app backend) where a significant portion of Django's niceties (and there are many) are irrelevant to what you're trying to accomplish.
And seriously, if you replace every Django component with something else you probably picked the wrong tool for the job.
I brought up Flask and asked him what he thought of it. I had recently used it for a project for the first time and likely only did so because I was SUPPOSE TO BE FOCUSING on Django and preparing a talk about it. So naturally, I procrasinated and did everything but. It's been on my radar for awhile. I was attracted to it by it's documentation. Turns out, I really enjoyed it. It felt familiar because I've used Django for so long. I brought this up at the dinner table.
Jacob said something that took me by surprise. I can't quote him exactly--the wine and drinks were too good that evening, but it was something to the effect of "Flask is what Django should have been". Another fellow from our table chimed in and added "If only Django had existed before we created Django!" What he ment was, without Django, Flask wouldn't of had such a clear and smooth start. Django taught us a lot.
What I took from this was, both have their place and we have a lot to be thankful for, especially coming from the Django community. In regards to longevity, I think community is a major factor but these two technolgoies are both under Python, and I think the Python community at-large is what matters here. Hearing what Jacob had to say on Flask was sobering. There is no end-all-be-all, and both of these technolgoies have more in common than not.
if you go with django, then in the long term,
you will have to replace almost every single component
of django with something else, the only remaining part
will be the url mapper.
That has been exactly my experience with a project and it has eaten a lot of time It is the single reason why I'm abandoning Django. Batteries are included, but they are Double DD batteries when I need AA, AAA, etc, etc.Its fine if you decide that you don't want to use Django and build a more modular stack with components of your choice. If you decide to use Django you're deciding that you want to use Django's ORM, URL routing, util libraries, etc. These are all really high quality components that do their job well. There's no good reason to replace them once you've started using them.
Yes, there is a need for manual SQL queries sometimes, and heavy caching, but for the most part it works ok.
I'm not sure I can disclose the exact company, since I left them recently, so I won't, unfortunately.
edit: some background on pyramid's design: http://docs.pylonsproject.org/projects/pyramid/en/latest/des...
"Closed because there is a fair chance it will not be constructive" maybe? "Closed because this and this and that person felt there where a fair chance it would not be constructive?"
Oh, by the way: discourse is still a sandbox it seems: from http://try.discourse.org/ - "THIS SITE IS A SANDBOX – it is reset every day"
Django app concept? It's good, but what if a single app grows too big? Split two apps? Then what if a project has hundreds apps? We should break down with python modules and packages for a large software.
Flask is simple, and it's good for beginners. But is the simplicity helpful for a long-term project? It saves only learning curve of first week.
Django supports many features and that's also good, but it only saves time to develop the features. Because flask already supports a lot, the saved time would not be much for a long-term project.
Django or Flask matters only for small projects, such as one month long. The choice doesn't matter for a large project. Yes, django template sucks, but you can change to mako or jinja or something else. You like django ORM? That's a good news, but even if you don't like it, you can use SQLAlchemy in django. Such changes can be wastes of time for short-term project, but no problem for large projects.
Code pythonic. That's the answer.
http://docs.pylonsproject.org/projects/pyramid/en/latest/nar...
Bloated also tends to mean things like "takes up way too much conceptual space". Which is a valid argument against a lot of frameworks. The idea being: i have to learn to think about the problem in the framework's way, and restructure my solution around it.
The opposite being: with micro-frameworks I can just wrap my app with the framework and get some functionality out of it that would otherwise be difficult or boiler-plate.
(The counter-counter being: then you end up having to reimplement a buggy version of a full framework anyway as requirements grow and change...)
The real solution is to not think of it as either/or , but as "both, sometimes".
A) It works together. The framework is a framework as a whole, so you can expect all the components to work together, without having to fudge things, or crate workaround for things that don't want to play nicely together.
B) There should be some consistency in the components and the way they are used. That should theoretically lower the cognitive load, if that's the "bloated" that people are complaining about.
See also people who pore over "hello world" benchmarks, etc.
Authentication - Django provides UIs that you can skin/replace, and there are Django applications to do OAuth for you. With Flask there are plugins, you have to provide a UI (and UI workflow).
For almost everything Django can do, there is Flask plugin.
You might be able to put together simple sites faster with Django, you will get more flexibility with Flask.
http://flask.pocoo.org/docs/blueprints/
Like the rest of Flask, it's well thought-out and flexible.