codestasis 5 years ago

Congratulations to the Django project and contributors on a big LTS release. And a huge thank you for the consistently excellent framework that so many have built their web dev careers on.

I'll post this as a Show HN soon, but I'll mention it now as a soft-launch introduction. After a decade of using Django I started a project I always wanted to exist: backported security and bug fixes to old versions that the Django project has dropped support for.

I've seen many Django projects eventually get stuck on an old version as the team I'm on is forced to defer upgrades in favor of commercial pressures and essential product delivery.

So you can subscribe to https://www.codestasis.com/ to stay patched on your old version, removing the urgency to upgrade. Then unsubscribe when you're caught up.

It's free for personal use and a paid subscription for businesses and organizations.

  • vagrantJin 5 years ago

    > It's free for personal use and a paid subscription for businesses and organizations.

    This is awesome.

    • codestasis 5 years ago

      Thanks :)

      I also want to experiment with reduced pricing for non-profits, but first have to get the basics down and ship the free and enterprise versions.

      And then pay back a huge debt to Django with code contributions and corporate sponsorship.

    • mherrmann 5 years ago

      I think it's a bad idea and would recommend grandparent to charge everyone for the service, then donate parts of the proceedings back to the Django project.

    • e12e 5 years ago

      Great project. Looks like running outdated Django will be cheaper than running outdated rails... Although I can't remember if there were multiple players delivering "lts" versions for ruby/Rails?

      https://railslts.com/

  • jsmeaton 5 years ago

    This is awesome, good luck!

    It's a project/business that I've suggested a few times on the mailing lists and I'm truly surprised it's taken this long for someone to start one up. I'll be interested to see how/if the price points change over time.

    The pro tier is approximately equivalent to <= 5 hours of developer time per month. At a minimum it gives useful information to developers trying to communicate the cost of delay to management. I think my org may have opted just to pay at one stage, considering the migration from 1.8 to 1.11 was measured in weeks not days.

    • codestasis 5 years ago

      Thanks! I toyed with the idea since 2014, after I was stuck managing a Django codebase with a gnarly middleware for a multi-tenanted website that precluded an easy upgrade.

      I bookmarked this thread in 2019 where tptacek provided the impetus for the project with a one-liner suggestion https://news.ycombinator.com/item?id=20378409 And I've just noticed you replied then too!

      I also assumed someone would get around to it. It took a while to get to a place I could start and then way longer to develop than I assumed. (Not just the backports but the tooling, testing infra, and website)

      That's good to hear on pricing since it reflects my experience and is my thinking behind the initial price points.

  • danjac 5 years ago

    This is a great idea...unfortunately a company that skips on Django security patches and bug fixes will very likely be doing the same for everything else (frontend libraries, servers, etc). But there's not much you can do when you're stuck on a feature-factory treadmill, and this looks like a cost-effective way to ameliorate the problem.

    • codestasis 5 years ago

      Yes, that's why I optimistically chose a generic name for the project. Django is a solid start and I sure have tons more work to do.

      Then there's an opportunity to expand to adjacent projects it could make sense to cover.

      There's lots of thinking to do, approaches to try around funding the original projects and authors, and happily aligning incentives.

  • dangerbird2 5 years ago

    As someone maintaining a bunch of django services in need of TLC, this could be a lifesaver for me. Thank you!

  • a_c 5 years ago

    Awesome project! Bookmarking for sure. Dumb question: after signing up, am I getting some access to a privately hosted repository(pypi.codestasis.com)? How is the mapping between personal/pro plans and features done? Are different plan levels using different repository?

    Btw, might have overlooked, if I'm purchasing for my org, I would like to look at the commercial license. Can you point me to it? Or put it online if not currently available? I'm not using your service at this moment, so feel free to ignore the request as well.

    • codestasis 5 years ago

      Not at all, good question. You do get tokened access to a private PyPI package index, specific to your account and subscription.

      At the moment the personal and pro plans use the same repo and infrastructure. But pre-release packages will be listed only for pro accounts.

      Here's a preview of the software license (also linked from the subscription page): https://www.codestasis.com/buy/pro/software-license/

  • darkhorse13 5 years ago

    I genuinely love the fact that you have been able to build a company providing support for Django. I find that seriously inspiring.

  • rbut 5 years ago

    What a great idea. We’ll be subscribing as soon as the 1.11 support is released.

  • jacobian 5 years ago

    This is so cool, I’m really glad to see someone doing this. Best of luck!

    • codestasis 5 years ago

      Cheers, that means a lot. Thanks for starting something truly great all those years ago!

KennethPT 5 years ago

Django is the gold standard for consistently pushing out reliable, well documented open source software without any marketing fluff or other bs. The amount of value the team is adding to the world can't be overstated.

  • peterpostman 5 years ago

    A couple of years ago(2014) I made my first Python website and really enjoyed, however when it was time to put it onlin I quickly discovered that setting up hosting and configuring it was as large a task in getting to know pip, env, unicorn, apache2 and a plethora of other software to host it, is this still the case? Becaue this is what keeps me of hosting websites with python.

    • airstrike 5 years ago

      You can always shortcut things by using Docker

      • dangerbird2 5 years ago

        You'll still have to configure gunicorn or another production-ready (w|a)sgi server to serve the app out of the container, but it's much easier to manage dependencies for django in a containerized environment. It's even easier if you use a deterministic package manager like pipenv or poetry instead of old requirements.txt files

      • collyw 5 years ago

        Adding an extra layer doesn't make things simpler. It may make it easier to do a second time, but the initial set up is just the same.

    • Sileni 5 years ago

      At least with pip and env, you'd have a hard time doing general tasks in python without getting to know them anyway.

      You can also shortcut a lot of that with a hosting service like Heroku, which takes on a lot of the mental overhead for you.

      You've made me curious to ask, what programming environments don't have a significant learning curve when you get to the hosting portion, short of a "no-code" hosting solution?

      • chipotle_coyote 5 years ago

        PHP. Deploying small-to-medium PHP projects to production has historically been "move these files to your web root, initialize/seed your database if you have one, and that's it." It's really easy to underestimate how valuable that is in certain contexts, and how much that's contributed to PHP virtually owning the low end of the market.

        My assumption was always that other languages would find a way to get closer to that model -- never quite to that level for various technical considerations, but close. I'm not sure any really have, save, as you noted, through dedicated hosting services. Fortunately, though, modern PHP frameworks have come to the rescue by becoming far more difficult and fiddly, to the point where both Symfony and Laravel's online tutorials begin with installing Docker.

      • hallman76 5 years ago

        > You've made me curious to ask, what programming environments don't have a significant learning curve when you get to the hosting portion, short of a "no-code" hosting solution?

        With java you can deploy a "fat jar" - a single executable that contains everything it needs, including the web server. You start the jar, it binds to a port, and you're done.

    • EmilStenstrom 5 years ago

      I recognize this from some years ago, but it's not an issue any longer, as long as you go to a modern host (ie. Heroku). The old "optimized for PHP"-hosts still make things hard of course...

      • number6 5 years ago

        Having set up some php servers myself: it's not a lot harder to host a python app. It is mostly the that hosters have optimized for php but you could do the same for python

    • illnewsthat 5 years ago

      I had similar issues with Django where I felt that running on localhost was fine, but getting it production ready was a headache.

      Huge shoutout to dokku[1] which I used on my latest deployment and it makes it super easy. Lets encrypt support was the easiest I've seen and you redeploy with git push.

      [1] https://dokku.com/docs/getting-started/installation/

      • robomartin 5 years ago

        Interesting.

        How does dokku work with regards to mixed multi-hosting (Apache virtual hosting) on a server?

        For example, you have five sites, three are PHP and two are Django. Can it deal with that?

        Also a neat "for free" feature of CPanel hosting is that you get super easy email hosting. This can save a lot of money for small and medium businesses. While some would be interested in using Django on these systems, it is in a range between painful and impossible.

        This means that you have to now switch to a single-app/domain-per-server scenario (like, Heroku) which is expensive. And then spend more money to host your email elsewhere.

        Frankly, this has been one of the largest sources of friction for me with Django. I love the framework and would like to use it exclusively but the transition from local development to deployment can be daunting.

        • wilsonfiifi 5 years ago

          Dokku will allow you to host multiple applications on subdomains for which you can create CNAMEs in your DNS settings. Dokku is more of a mini self hosted Heroku without a dashboard so you'll lose out on cpanel features like email hosting.

          But If you're not uncomfortable using docker, you can check out Cloudron [0] which handles email [1] and gives you access to quite a few web apps you can easily install on your server. It supports PHP app deployments [2] out of the box but for Django, you'll have to dig a bit deeper into their docs to learn how to deploy a custom docker based app [3].

          [0] https://www.cloudron.io/

          [1] https://docs.cloudron.io/email/

          [2] https://docs.cloudron.io/apps/lamp/

          [3] https://docs.cloudron.io/custom-apps/tutorial/

          • robomartin 5 years ago

            BTW, it's not that I am not confortable with Docker. In fact, we use it for development. This is more about time and resources. I run more than one business and a couple of them have more than one domain. We pay for a decent VPS and can host and manage as many email addresses and applications as we want. Yet we have to limit it to PHP (either pure PHP or something like Wordpress). And, BTW, I hate using PHP.

            For internal stuff we use Django for everything. Host it locally, etc. We even use Django as the front end for industrial automation applications (which imposes interesting challenges, like maintaining state in the database as well as reliable activity logs and more).

            If I were to summarize the difference between doing Django for the web vs. PHP for a business it would go something like this:

            PHP: Get almost any server. Setup the domain, emails, setup database, upload code. You are up.

            For Django you could do this (some of this is dated, just making a point):

            https://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django...

            or this:

            https://www.gjlondon.com/uncategorized/the-idiomatic-guide-t...

            or this:

            http://www.robgolding.com/blog/2011/11/12/django-in-producti...

            or this:

            https://developer.mozilla.org/en-US/docs/Learn/Server-side/D...

            In other words, you are way past the beauty and simplicity you got during local development.

            And, of course, for most, if not all, of the above, you still have to deal with setting-up business email. Which means you either get the same VPS you got for the PHP case and point the MX record that way or, spend a bunch of money per email address with something like Gmail. Etc.

            Django is fantastic. Somehow, someone needs to figure out how to be able to launch the same type of site you might develop locally to a standard VPS just as easily as what is possible on your local development system. Yes, of course, for more advanced sites you are into separate DB, static, application, etc. servers. That's a different use case. I think what people are saying is that there's a great divide between "runserver" and actually being on a server from there without paying more for specialized deployment services.

            Another way to look at this that Wordpress will never be challenged at scale if a better tool like Django isn't easily accessible to developers who are not Linux/server experts. I was running Unix before Linux came out and have used Linux in various forms (including early embedded systems applications) since the beginning. If someone like me recoils at the idea of actually deploying Django in the real world I can't imagine what this might feel like to others who might lack the experience.

            In other words, I can do the work. I just think it's unnecessarily complex and not enough effort has been expended duplicating the ease of local development for basic to mid-range Django apps at the production server level.

            • bjourne 5 years ago

              That's true. Every time I have to launch a new Django site I always have to spend an hour or two reading docs to refresh my memory on how to configure everything. SSL, systemd services, certificates, uwsgi, database setup, permissions, dns, email, etc. Someone could probably make a lot of money by creating some kind of Django+uwsgi+docker+nginx+postgreSQL bundle to make this process as painless as possible.

              • robomartin 5 years ago

                Here's one way I look at it. I don't need or want the simplified local development environment. As neat as "runserver" might be, it actually creates a problem, because going from there to production feels like the difference between driving on a lazy country road on a beautiful summer day to driving in the middle of one of the most chaotic cities in the world in a storm.

                My humble suggestion would be that this form of easy local development should be deprecated in favor of creating a server-based local development model that translates 100%, without friction, to production servers.

                Simple example, I do all my web development work either using a Linux server VM on my Windows machine or a Linux server on our network. These days, running a VM with whatever flavor of Linux isn't a problem for anyone. Django could, out of the box, come with such an arrangement for local development. Perhaps in the form of an Ansible script.

                I would want to see at least two development scenarios supported. The first would be as close to bare metal as one might want to get (say, Linode) and the other should be setup to work on something like a GoDaddy multi-hosting VPS.

                This would allow for frictionless transition from local development to production deployment for a huge class of sites. Anyone doing anything more complex than that would have the time and maybe even the engineers to devote to designing and deploying a complex infrastructure with multiple kinds of servers, load balancing, etc.

                Bottom line is, I think "runserver" is a neat trick but it likely ends up causing far more frustration than might be obvious. I have spoken to a number of people who tried Django, liked it, and moved on in frustration when they hit a brick wall when they had to figure out deployment.

                I like to say that people don't go to the hardware store to buy a drill bit. What they are after is a hole. It's the same with websites. Nobody needs a Django website. Nobody. There are a bunch of alternative technologies out there. Which means that if Django makes "getting a hole" difficult, people will just move on. They don't want to become experts in manufacturing drill bits, they just want a hole.

        • illnewsthat 5 years ago

          I am definitely not a dokku expert (for that I would recommend reaching out to their Slack channel[1] - a lot of great support for an open source project).

          But in an attempt to answer your questions:

          - Yes, you can host multiple sites on one server in dokku.

          - That's a good point, I'm sure a lot of people like that about CPanel hosting. Maybe something like this poste.io implementation[2] would be what you are looking for?

          - Dokku has the benefits of heroku but without the vendor lock in/pricing. Pick your preferred VPS host that runs for a few dollars a month and you are set.

          [1] https://dokku.com/docs/getting-started/where-to-get-help/#th...

          [2] https://github.com/D1ceWard/dokku-posteio

    • canadapups 5 years ago

      I just migrated to PythonAnywhere.com and it was a breeze. They also have browser access to command line, REPL, Jupyter notebooks too.

    • ahmedfromtunis 5 years ago

      I was in a similar position a few years ago too, until I forced myself to learn Docker.

      Now, all my projects are started from the same building blocks: Docker + Django + Gunicorn + Nginx + Postgres. And I love it.

      Now I have traefic at the top of My to-learn list so that I can host multiple projects in the same VPS.

      Last weekend I learned to use 11ty — the first static site generator I managed to grasp — and I'll entend to use that for projects that don't need this level of "complexity".

      • williamdclt 5 years ago

        If you don't want to go the docker route, there's a few Django boilerplates around with an Ansible configuration

      • bjourne 5 years ago

        > Now I have traefic at the top of My to-learn list so that I can host multiple projects in the same VPS.

        Why do you need that? Nginx dispatches based on the domain name so you can easily host multiple Django sites on the same vps. I use the same tech stack as you except with uwsgi instead of Gunicorn.

buffalobuffalo 5 years ago

A couple thoughts on django as a long time user. First, the good:

- Django was the first framework i learned when learning to code. It's documentation was amazing, and it made conceptualizing an MVC framework really easy.

- Django's ORM is phenomenal for managing migrations of a relational database, especially postgres with stuff like jsonb. I've even included it in non-python projects, just to handle table migrations/rollbacks.

- The huge ecosystem is amazing. Great for rapid prototyping. Plugins for all kinds of crazy stuff.

Now the bad:

- In some ways it feels like a relic of an earlier stage of python. It's support of asyncio is spotty at best (running the orm in a thread executor not a good work around).

- It's support for type enforcement with mypy is not great. This is maybe my biggest issue with using it on large collaborative projects.

- It doesn't play nicely with a lot of the rest of the python ecosystem. Want to swap in SQLAlchemy? Sorry, no dice. Want to have nice swagger documentation? Use django rest framework or you're out of luck (i know it can be done, but it's kind of messy). So in short, it's a bit of a monolith.

These days I tend to only use django for it's orm in situations where i want a quick ad hoc database for something, or for rapid prototyping. If I'm going to do a larger project in python, I'd definitely go with FastAPI. But still, gotta appreciate that it's there, and has been reliable/well maintained for more than a decade.

  • yhoiseth 5 years ago

    How productive are you with FastAPI compared to Django? I’m thinking of things like forms, error handling and all the other extra stuff that comes with decoupling the frontend and backend.

    • skrtskrt 5 years ago

      The main thing I would wonder about is if there's a good auth plugin for FastAPI.

      I am not a huge fan of Django, but if you have already chosen Python, it is really hard to argue with having good, battle-tested auth system out of the box.

      • buffalobuffalo 5 years ago

        The other side of the coin is that django's auth system is pretty rigid. Adding additional fields to the user object is clunky, and trying to do an unusual auth flow can be downright ugly. Dealing with that a few times can leave you a lot more open to designing your own and/or patching together other libraries. At least, that's how it went for me a few years ago.

        • hdbsjahxb 5 years ago

          Django allauth handles 90% of auth needs. Adding fields to user is easy if you set it up correctly

    • buffalobuffalo 5 years ago

      Not nearly as productive. That's why django is definitely a better choice for rapid prototyping. But if I'm working on a larger project that I'm hoping to maintain for years, up-front productivity usually takes a back seat to maintainability/scalability/extensibility. For those, I'd go with FastApi

  • pydry 5 years ago

    >- It doesn't play nicely with a lot of the rest of the python ecosystem. Want to swap in SQLAlchemy? Sorry, no dice.

    Being extremely opinionated about stuff like ORM and admin is partly how it developed such a rich ecosystem of plugins. Those plugins exist because they can build upon those foundations.

    Flask, by dint of being unopinionated doesn't have solid foundations that its plugins can build upon. This is why you get stuff like quokka (a flask cms plugin built on mongo) while other stuff assumes sqlalchemy and other plugins built plugins for various different storage backends.

    • buffalobuffalo 5 years ago

      I think you could probably abstract away some of the differences between djangoORM and SQLalchemy. Maybe something like a model class that uses sqlchemy for the underlying orm interactions. Not that i really blame them for using their limited dev resources elsewhere.

  • kstrauser 5 years ago

    I've summarized this elsewhere:

    Django is really great for writing Django apps. It's not great for writing other kinds of apps.

    If your app is a CRUD interface over a relational DB, it's awesome and I mean that sincerely. I'll happily reach for it instead of reinventing that nicely crafted wheel.

    If your app isn't -- say, it's backed with noSQL or maybe is a frontend over a bunch of backend API calls such that you're not using its ORM or its permission model -- then it feels like a box of pain.

  • hdbsjahxb 5 years ago

    You can absolutely use sqlalchemy

nickjj 5 years ago

If anyone is curious I just updated my Docker / Django starter project to use 3.2. It uses Docker Compose + Django + Celery + PostgreSQL + Redis + Webpack + TailwindCSS and it's available at: https://github.com/nickjj/docker-django-example

As an aside it's also using TailwindCSS 2.1 with the JIT compiler enabled.

  • danjac 5 years ago

    Just upgraded my side project to both Django 3.2 and Tailwind 2.1 (with Jit enabled). No issues at all, other than some deprecation warnings on some 3rd party packages that will probably be fixed soon.

    • sgt 5 years ago

      Looks really good. What made you choose Tailwind over the alternatives?

      • danjac 5 years ago

        I've used more component-based frameworks like Bootstrap before, but I've found it's easier to have a set of utilities and build my own components on top of that.

      • ehou 5 years ago

        We use TailwindUI - combined with Django gives a really nice kickstart on new projects. Just made a Proof of Concept last two weeks for an internal business app for a new customer and did impress them easy with a working app + login + responsive nice looking layout. Used VUEjs for menu's, keyboard events and a location picker.

  • fatsdomino001 5 years ago

    Why celery and redis? Couldn’t you consolidate with just redis? Love the stack though

    • number6 5 years ago

      Django_Q instead of Clerery

    • williamdclt 5 years ago

      Celery describes itself as a "task queue" but I find it a bit confusing: it's a job manager, which needs a queue from which to pull/push jobs. Redis is this queue

  • dopeboy 5 years ago

    This is awesome, thanks for sharing. I maintain a similar boilerplate (graphene + semantic ui).

    What's your take on Tailwind so far? I've found the lack of a react offering has really slowed me down.

    • babelfish 5 years ago

      The creators of TailwindCSS also have a paid offering called TailwindUI (just pre-created components with documentation for your application and marketing site) that has React support. It also comes with Figma mockups for each component. It's a bit pricy but very high quality.

      • tracyhenry 5 years ago

        I never used Tailwind but given its popular modern look, I wonder why there is a lack of open source React components built on top of it?

    • nickjj 5 years ago

      > What's your take on Tailwind so far? I've found the lack of a react offering has really slowed me down.

      It's working out well for the most part, but I don't use React.

      I mainly develop server rendered apps and sprinkle in JS as needed.

      The only weak link with Tailwind IMO is the lack of JS for doing common things like hiding / showing menus, tooltips, modals, tabs and other stuff you'd find baked into Bootstrap. I know there's some JS included in the TailwindUI components but it's not for JS libraries that I use. I prefer using StimulusJS which isn't something they support at the moment.

      Fortunately there's a bunch of StimulusJS Tailwind examples provided by the community so it's not too bad in the end.

      I imagine it's hard for Adam because there's React, Vue, Alpine and StimulusJS, all of which are popular enough where there's a good amount of users using them. I'm optimistic that he'll think of a way to cater to all of these users in some way, it'll only be a matter of time. NOTE: This is just speculation, I'm not affiliated with Tailwind in any way.

  • sgt 5 years ago

    I went back to this thread to find the docker-django-example. I have to say, this is really solid work, and thank you for sharing it. Tailwind is commercial I see, is there a free way to get set up with a nice looking "dashboard + sidebar" UI without buying the Tailwind UI?

gregasquith 5 years ago

Django is a sensational piece of open source software - I've used it on so many projects.

Seen some replies saying it's a pain to deploy - look at guides for Heroku and Google's App Engine - both are super simple processes. If you want more control AWS Lightsail also has a great guide.

pytlicek 5 years ago

I have been using version 3.2 since Beta. Deployed on a production application, so far without a single problem. I highly praise Automatic AppConfig discovery and BigAutoField for pkey. I highly recommend the transition to Django 3.2

Full release notes: https://docs.djangoproject.com/en/3.2/releases/3.2/

alwaysanoobie 5 years ago

Any one have any pointers to learn the Django stack from the basics? Any specific video course or a book?

"Two Scoops of Django" was recommended to me by someone on HN. I think it is currently being worked on for Django 3. It is on my reading list.

  • caioariede 5 years ago

    Two Scoops of Django and the Django Tutorial itself are amazing. I highly recommend both.

  • onepointsixC 5 years ago

    Two Scoops of Django is probably one of the absolute best books to read on Django. I would read that before looking for anything else.

  • greenie_beans 5 years ago

    I wouldn’t start with Two Scoops if you’re trying to learn “the basics”. Check out the MDN django tutorial

  • canadapups 5 years ago

    Tango with Django was by far the best resource I've used.

    Two Scoops is more for people who have a django project already and want to learn best practices of django.

    • nanna 5 years ago

      The latest version of Tango with Django is from 2019 and is compatable with Danjango 2.2. Has a lot changed since then, if one was to work with 3.2?

      • canadapups 5 years ago

        My website was built in the 1.x version days and I don't think there have been any material breaking changes. My website is moderate in complexity... authentication, database, forms, file uploads, email, language support.

        • nanna 5 years ago

          Thank you!

  • collyw 5 years ago

    The official Django tutorial is pretty good. Two Scoops is good for going from beginner / intermediate to intermediate / advanced knowledge, with best practices in mind.

  • esaym 5 years ago

    I would grab the "Django Crash Course" from Feldroy[0]. It is a tutorial starting from nothing, and you build a very basic app. Which sounds unimpressive, but it shows you all the best practices for app layout etc and when combined with Two Scoops, provides a great foundation.

    After that, to really get to know Django, you'll want to do some "unconventional" things like use a class based view for a page with 3 forms... That should give you the "ah ha" moment.

    [0]: https://tinyurl.com/2hkhd6px

pantulis 5 years ago

Before Django the gold standard for Python web apps was Zope. What a tremendous achievement by the Django team!

  • rhizome31 5 years ago

    Not sure if a lot of people on HN are old enough to remember that :)

    • Andrew_nenakhov 5 years ago

      Not many have ever heard of it, but everyone has seen the design that borrowed from the most well-known software that used Zope - Plone.

      Of course, I'm referring to the early design of Wikipedia, which closely copied the design of Plone.

    • fullstop 5 years ago

      In my mind HN skews older, but I have no idea why I think that.

      For what it's worth, I definitely remember Zope.

    • pantulis 5 years ago

      Well, that's what I'm here for ;)

  • Andrew_nenakhov 5 years ago

    Zope? Now, that's a name I haven't heard in a long time... A long time.

    I wonder of this magnificent monstrosity is still alive?

  • adiyatmubarak 5 years ago

    I thought Pyramid is old enough, but I just heard this Zope

  • fulafel 5 years ago

    I remember Zope was pretty universally disliked by Python programmers. But it was for a time probably the most enterprisey thing with Python inside, so maybe it got more points in corporate places as something to try as an alternative to Enterprise Java Buzzwords.

    Before Django there was a lot of choice and active libraries / frameworks for Python web app development, IME most apps gravitated more towards "ala carte" use of libraries than one size fits all frameworks, a bit like people do in Clojure today.

    Zope was more like a ready to use CMS that incidentally enabled you to mod it using Python in a clunky way.

    The object database part of Zope (ZODB) was pretty cool though, used separately (inside Zope the framework-enforced object schema made it just clunky). As long as you didn't let it spread too wide over your codebase. But it had transactions, flexibility of (and problems of...) schemaless, and replication, a long time before the "NoSQL" craze.

    • fulafel 5 years ago

      Replying to myself: for those interestedin ZODB, there's also a simpler standalone remake called Durus (by well known Pytoneer Neil Schemenauer): https://github.com/nascheme/durus

      It might not have the replication / distributed features though.

  • dagw 5 years ago

    I recall there being some 'wilderness years' between people generally deciding that Zope was a bad idea and Django 'winning'. I remember using frameworks like Turbogears and CherryPy for a while before Django and Flask split the 'market' between them.

    • rodelrod 5 years ago

      This is how I was seeing things play out in the early 2000's: — Python Programmers: why do we still have to be doing this in php/Perl/JSP/ASP when Python exists? — The World: here's Zope — Python Programmers: is that supposed to be joke?

      Then in 2003 WSGI showed up and it was a matter of time, leading to the years of wilderness that you describe until Django won out. I confess that I was more team Pylons, but happily conceded.

  • teilo 5 years ago

    Ah, Zope, that wonderful monstrosity. I build a purchase order system for my company in it back in the day. It made that type of business app very easy, as long as you didn't expect any kind of performance or scalability. The magic of Zodb was also its weakness. But even today, I think it would still be faster to develop a basic business app in Zope than in Django.

varispeed 5 years ago

Django is so refreshing when you come from JS world. Combined with Python is such a pleasure to do stuff with it. My favourite model is Django backend and React frontend though (I try to keep it as lean as possible). Congrats! Looking forward to update my projects.

ziggrat 5 years ago

Django rocks. I have been using it in every side project of mine since 2016. Love it, recommend it especially for teams with very less time and more features on backend.

jfdi 5 years ago

<3 to Django team and community. Thank you for your continued great work and congrats on this latest LTS!

godmode2019 5 years ago

I'm more if a flask man myself. Worked with django only when I had to.

Maybe I'm wrong?

  • hnarayanan 5 years ago

    You should try it, it’s really all batteries included.

    • jtdev 5 years ago

      The ORM is horrendous.

      • Nextgrid 5 years ago

        Can you elaborate? I've been using it for years and it mostly does what I want. It's an ORM and obviously sometimes generates unefficient queries I need to manually amend/refactor but otherwise I don't see any major issues with it?

        In contrast I've looked at SQLAlchemy with Flask and I couldn't even wrap my head around declaring models (which inherit from the DB connection object if I remember correctly, so potential for circular imports) and manually managing transactions/sessions seems unnecessarily complex.

        • grenoire 5 years ago

          Comparing Django vs SQLAlchemy, Django's weakest point is its extremely static ORM syntax. The double underscore separation (e.g. user__group__name__icontains) for query parameters is likely my biggest pet peeve as it requires me to unroll unchecked strings together into a big garbled mess. I would have much appreciated being able to use more code-verbose query tools; the moment you have to go into building more dynamic user-defined query systems, Django's ORM just becomes a hindrance.

          I also noticed the second part of the comment: Django does a lot of Python magic in the background through extensive use of reflection and class-level declarations, this hides away the abstractions (again) at the propose benefit of ease of use. And well, it is easy to use. For certain applications. I just personally found a lot of footguns trying to work with more advanced Postgres functionality (mainly around JSON) and it took a while to write my own abstractions atop the Django ORM to get to a comfortable level.

        • sonthonax 5 years ago

          The inability to batch network calls in a single unit of work makes the ORM needlessly slow. That's also one of the main advantages to managing transactions/session yourself. It can save a huge number of round trips in a complex view.

          The Django ORM itself is also slow at generating SQL. Recently I was bemused by a query, which took 500us to actually be generated. This wasn't doing anything particular wild, it just had a `select_related` call to an object that had about 50 fields (not great DB design, but beyond my control). The query actually took longer to build than it did to run.

          That itself wouldn't be an issue if you could LRU cache the SQL query itself. But you can't, it's Django.

      • hda111 5 years ago

        The only thing I don’t like in the ORM is that it doesn’t force you to use transactions.

  • BiteCode_dev 5 years ago

    Django fan here. You are not. Several frameworks exist to satisfy several needs and profiles.

  • helb 5 years ago

    I'm more of a Django man, worked with Flask only when i had to. There's no "wrong" or "right" in this…

    • Chris2048 5 years ago

      Then why not work with PHP?

      • leetrout 5 years ago

        There’s nothing wrong with PHP. And Laravel is very popular for good reasons.

        There are people out there writing Python just as bad as what you think of as bad PHP.

        One dev I knew insisted everything must be a list comprehension — including all for loops in regular flow control. That was Not Good(tm).

        ———

        Edit: please read the parent comments for context. GP said there’s no right or wrong and OP said then why not use PHP and I said it’s not wrong.

        • Chris2048 5 years ago

          > There are people out there writing Python just as bad as what you think of as bad PHP.

          By that logic: there are people "out there" jamming pencils up their noses, therefore a shovel is just as good a writing implement as a pencil..

          • leetrout 5 years ago

            Sure. It’s up to the end user to use the tools in an appropriate way.

            There are a ton of inconsistencies in the PHP standard library and I’m not defending that but that doesn’t make it “bad” as you insinuated.

            • Chris2048 5 years ago

              Then lets look at those semantics: what is bad, and is anything ever bad? Because I think mostly all frameworks are pretty easy in the small, it's how they help/hinder with larger projects that demonstrates their worth.

              On that basis, sure, it's up to the user to figure out what's appropriate; and a shovel is not an appropriate writing implement - you could say it's even a "bad" one.

        • acdha 5 years ago

          I generally agree philosophically but PHP has a couple of features which make problems more likely: the C style error handling increases the odds of problems being ignored (yes, Python can have except:pass but that’s more obvious & requires intent) and the mushy typing hits even experienced developers who didn’t think about whether they needed === instead of ==. The standard library’s inconsistent parameter ordering for related functions probably deserves a mention here, too.

          I started using PHP around 1998 and quit cold-turkey about a decade later for Python after noticing across the board quality improvements on every project. PHP isn’t terrible but using it requires constant diligence and few teams had the extra time and skills to use it safely.

          • leetrout 5 years ago

            I think the tooling we have in the Python ecosystem far exceeds PHP and I agree (and mentioned below) about the inconsistencies.

            Been a long time since our chats at DC Python. Hope you’ve been doing well, sir!

            • acdha 5 years ago

              Heh, yes, it has been quite a while. Pandemic pre-K has been quite the adventure so DC Python seems like a fairly distant memory ;-)

  • elitepleb 5 years ago

    At some point using Django just makes more sense.

    No need to reinvent the universe for bigger jobs.

  • pytlicek 5 years ago

    I also used Flask and I wasn't a Django fan. But this got me on larger projects, when Django and his "Batteries Included" made sense. Now I will soon think about the size of the project in advance, and based on that I will choose Django or Flask. There really is not something wrong here. Everything has its pros and cons.

  • loloquwowndueo 5 years ago

    Right tool for the right job. You’re not wrong unless you are - if as others said you’re reinventing the wheel on flask, or are doing a very simple API service in Django which doesn’t use most of its facilities (like the admin) and could easily be done in flask.

  • danjac 5 years ago

    Depends what you want to do, and why you're doing it. Very often when I make something in Flask, I end up with so many dependencies it might as well be Django (but without the cohesion). On the other hand, Django might be overkill in some situations (e.g. a small API without a relational database backend).

    • otherme123 5 years ago

      I was forced to fall on this trap once: a guy has a small Flask app up and running, and he asked for help to implement: an ORM with migrations, an Admin and form validation (among other things that had nothing to do with Django such file parsing).

      I suggested to migrate the app from Flask to Django while it was small and simple, but he refused for Django is "too big and complicated". OK, then. We ended up creating a monstrosity of Flask half-assed packages to include functionality that is already included in Django (think cache, csrf, admin...), plus WTForms, plus SQLAlchemy, plus Alembic, hard to test, hard to keep updated, hard to deploy, and so complex that it turned non-migrable to Django. Development felt like walking through mud.

      • dagw 5 years ago

        but he refused for Django is "too big and complicated". OK, then. We ended up creating a monstrosity of Flask half-assed packages to include functionality that is already included in Django (think cache, csrf, admin...), plus WTForms, plus SQLAlchemy, plus Alembic, hard to test, hard to keep updated, hard to deploy...

        Heh. I've done that. Impressive how quickly you can go from "I literally need three or four REST end points to let users query this SQLite database" to, well that.

      • andybak 5 years ago

        I like to paraphrase Greenspun's Tenth Law in this context:

        "Any sufficiently complicated Flask app contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of Django"

        • wirthjason 5 years ago

          I love the paraphrased quote. It’s a bit ironic in that Python programmers love the batteries included standard library but quickly jettison that idea when it comes to Django vs Flask.

          Flask’s marketing of a simple route decorator makes it seem light weight but once you add everything else it becomes Django.

    • varispeed 5 years ago

      Django has a substantial learning curve and you may need to spend more time to get started. But ultimately to do the same thing in Flask you have to spend comparable time to learn, except that Flask lets you start much quicker into your learning. As your Flask project grows you find out it is not actually that easy nor convenient. This is of course my experience only. I decided to just stick to Django (and DRF) and I feel no need to use anything else. For performant services I use Go.

    • wilsonfiifi 5 years ago

      I think one common misconception is that Django can't be used in place of Flask when you want a minimalist set up. And to be fair, I used to think the same until I read Lightweight Django [0]. Their smallest django project code is just a couple of lines:

          import sys
          from django.conf import settings 
          settings.configure(
              DEBUG=True,
              SECRET_KEY='thisisthesecretkey',
              ROOT_URLCONF=__name__,
              MIDDLEWARE_CLASSES=(
                  'django.middleware.common.CommonMiddleware',
                  'django.middleware.csrf.CsrfViewMiddleware',
                  'django.middleware.clickjacking.XFrameOptionsMiddleware',
                  ),
              )
              
          from django.conf.urls import url
          from django.http import HttpResponse
      
      
          def index(request):
              return HttpResponse('Hello World')
              
      
          urlpatterns = (
              url(r'^$', index),
          )
      
          if __name__ == "__main__":
              from django.core.management import execute_from_command_line
      
              execute_from_command_line(sys.argv)
      
      

      Granted, it's not as terse as Flask's hello world example but it's still quite short.

      [0] https://www.oreilly.com/library/view/lightweight-django/9781...

      • Avamander 5 years ago

        How big is the smallest Django project after you add proper authentication (signup, login, pw reset, oauth2, 2FA)? Last I checked it was rather terrible.

      • danjac 5 years ago

        I think the comparison is not so much lines of code but conceptual overhead. With Flask you create an app instance and call @app.route() with some Python functions and run the app. Granted it's probably not going to do much, and by the time you build out a real-world application with a SQL database, authentication and so forth you're going to get diminishing returns, but for a beginner who just wants to know "how do I make a web page using Python?" it's great.

  • mrweasel 5 years ago

    I doubt you're wrong. There's certainly a large set of problem that can be solved equally well by either framework. There are also projects where one is clearly a better solution.

  • codestasis 5 years ago

    I've had the opposite experience, working smoothly with Django for a decade except for one huge Flask project. Which essentially re-built Django... badly.

    I later tried and enjoyed Flask for a really small solo project, so I don't think you're wrong.

    Maybe there's a lot of implicit cultural knowledge on what packages work best to compliment Flask and the original developers on the big Flask project I suffered chose poorly?

  • holler 5 years ago

    I owe a lot to Django as it was really the thing that got me into backend programming by leading me to learn python in early 1.X days. My first real programming job was backend django programming for a newspaper. Eventually things shifted towards django-rest-framework, flask, and now my go-to Starlette. Haven't used Django in some time but really appreciate the project and happy to see it moving along.

    • leetrout 5 years ago

      Same here. Django 0.96 at the Washington Post.

      I start a new job next week at a Django shop after a couple years of JS and Go. I look forward to getting back to it but I will miss Go. :)

      • holler 5 years ago

        Congrats on the new job! I never really dabbled with Go, but a team I was on recently worked with a backend written in Go, and I was present in lots of discussions :) For current project I'm using Starlette/asgi, but I'm sure Go would have some advantages

  • Chris2048 5 years ago

    There's more choice in the flask ecosystem, but then again, you can suffer from poor choices and a lack of architectural consistency.

    I'd say the big thing is SqlAlchemy for Rel DB. and Maybe alembic to compliment.

  • teddyh 5 years ago

    Django has a few drawbacks:

    1. It’s tricky to use in non-web contexts. If you ever need something to happen as a response to an event which is not a web request, Django makes this difficult and ugly.

    2. Django also more or less requires ownership of the database in order to function as intended. If you want to have your Django objects in your own database and handle schema changes centrally (to, for example, alleviate problem 1 above), you must also abstain from some of Django’s power, i.e. migrations, etc.

    • andybak 5 years ago

      For (1) The simplest is probably just running a Django management command - maybe from a cron job.

      But maybe I'm misunderstanding the kind of task you have in mind?

      For (2) - you seem to be saying "if you don't want Django to handle migrations then you lose the benefit of Django handling migrations" - but again I might have missed some subtlety here?

    • flal_ 5 years ago

      For 1. I have found that a custom admin command can go a long way. If you want to be more "reactive" have a look at this asgi/channels thing... That or custom pythons scripts with the caveat of pointing correctly the DJANGO_SETTINGS ... As for 2. Well... Basically every ORM no ?

    • wasmitnetzen 5 years ago

      I'm using nameko and Django in a project, and haven't seen any issues with nameko just calling django.setup() and then the models and managers.

    • mtberatwork 5 years ago

      > If you ever need something to happen as a response to an event which is not a web request, Django makes this difficult and ugly.

      You are a bit vague but this is where message/task queues (e.g. Celery + a broker) come into play. Celery integrates with Django quite nicely.

  • chpmrc 5 years ago

    Honestly, I don't see the point of using Flask anymore. You can set up a Django project and just use a single module with a bunch of view functions, built-in testing and sensible defaults. Done. Not choosing that approach just because it takes a few more MBs on disk or needs a few more KBs of memory is shortsighted, IMO. You can't always predict what a project will end up needing.

    I'm legitimately asking: why would you use Flask instead of Django, even if you don't (but might) need the ORM, admin etc.? Thanks!

    • philote 5 years ago

      > I'm legitimately asking: why would you use Flask instead of Django, even if you don't (but might) need the ORM, admin etc.?

      If for some reason you wanted to use a noSQL database, Django's ORM and everything connected to it (like admin) won't work.

      • chpmrc 5 years ago

        There are connectors for noSQL databases as well. Or it's surely easier to implement one than to reimplement everything else around the ORM.

    • dagw 5 years ago

      why would you use Flask instead of Django

      If you don't really know Django, the learning curve on Flask is a lot shallower. So if you don't need ORMs, models, admin etc. but you just want make those python scripts you wrote callable via a web browser then you'll get version 0.1 out the door a lot sooner with Flask.

      Also a lot of Django kind of assumes the ORM as your data store. So if you need to use a primary data store that cannot be accessed via the ORM you lose a lot of what Django has to offer.

      That being said, I agree that many 'simple' Flask projects have a tenancy to grow until you have implemented most of Django in Flask anyway.

    • sonthonax 5 years ago

      Because Django is pretty badly designed, and it can get in the way when you need to do some more complex stuff. It get's the job done for 95% of cases, but that extra 5% can devolve into some pretty nasty stuff.

      Typically the inflection for when Django becomes a nightmare is when you want to start splitting the application up. This is made really hard because Django depends on a whole load of globals (settings, urls, context preprocessors, the actual WSGI handler). With Flask you can have two separately configured applications running in the same process, routed with a bit of WSGI middleware.

      This comes in handy when you need to do a 'soft' rewrite and have code running side by side. This also just makes things easier to test, because you can build a new application object for each test with it's own settings. You can't do that in Django with out a great deal of consternation; try creating two tests with different middleware stacks in Django, patching settings won't work because the application has already loaded, and there's no way to reload it between tests.

      Also, for the same reason (as someone else said) it makes it tricky to use in non-web contexts. Like Celery.

      Django's can't handle more complex database queries. If you've ever seriously used SQLAlchemy, you'll know what you're missing.

      The ORM is also lacking a unit of work model, which can kill performance. The only way to create multiple objects in a single database round trip in Django is with `bulk_create`. But you can't create something like a group and then a user in a single database round trip. Sure you can create them in a single transaction, but that's not quite the same, because each roundtrip takes an extra millisecond. It's an easily avoided inefficiency that SQLAlchemy solves.

      The template language is limited compared to Jinja2. While this is by design, it doesn't support streaming the response back. This is really annoying if you're generating massive templates. It would have also been really simple to do.

      I could go on really.

      • chpmrc 5 years ago

        You can use whatever ORM or templating library you want. But at least if one day you realize you need something that Django offers out of the box it's there for you to use.

        And if not it's not like it has any perceivable effect on performance.

  • philote 5 years ago

    I feel the same way. I like simple frameworks like Flask, Starlette, or FastAPI. Django feels too heavy for me, though I get why people like it. Maybe I haven't learned it well enough, but I often feel like I'm having to do weird things or fight the framework to get done what I need. Simpler frameworks fit my mental model better.

  • StavrosK 5 years ago

    As a rule of thumb, Flask is good when your app will only ever need to be a single file. Otherwise, as other commenters have said, you're basically reimplementing Django badly.

onepointsixC 5 years ago

What ever happened to the Async ORM? I thought that was originally supposed to be part of Django's 3.2 as part of their Async roll out.

vmsp 5 years ago

It's a shame that Django's templates are still so bad.

You can't just import and call some arbitrary python function. You most likely need to write a template filter or tag [0]. Maybe there's a good reason for this but it just feels like I'm working around a weird issue in the framework.

Also, I can't use parentheses inside if statements in a template. It's a strange restriction.

I know that Jinja2 -- which is good -- is supported. But it's a second choice, requires some setup and it's not the usual way of doing things.

Don't get me wrong. I like Django and it's still far, far ahead of most other web frameworks. But, because of these issues and also because the frontend story in Django is not that great I find myself reaching for Rails, these days.

[0] https://docs.djangoproject.com/en/3.1/howto/custom-template-...

  • question11 5 years ago

    I think a lot of developers have moved to reactjs calling an api.

    • collyw 5 years ago

      Basically doubling the complexity of an app. If you need a fair amount of front end interaction, fair enough, but many apps would be a lot simpler with Django templates and a bit of jQuery.

  • akuchling 5 years ago

    It is in fact deliberate, though; the "Philosophy" section on https://docs.djangoproject.com/en/3.1/ref/templates/language... explains it: "If you have a background in programming, or if you’re used to languages which mix programming code directly into HTML, you’ll want to bear in mind that the Django template system is not simply Python embedded into HTML. This is by design: the template system is meant to express presentation, not program logic."

    • vmsp 5 years ago

      That's something I think most developers would agree with, I certainly do.

      Still, I don't think what I mentioned is unreasonable or goes against the framework's philosophy. The templating system already has plenty of logical statements, might as well make it work like expected.

      See also Jinja2's take on that https://jinja.palletsprojects.com/en/2.11.x/faq/#isn-t-it-a-...

    • andyjones11 5 years ago

      The way I've seen this play out in reality is that a lot of the "presentational logic" required by the templates gets computed in the "Django Views" layer (akin to the "controller" layer in traditional MVC). So in the end Django views both perform business/service logic and presentational logic.

      I took it for granted after doing Django for several years but after doing a lot of web development in a more explicit MVC paradigm (Elixir and Phoenix in this case), my old Django code didn't really separate the web layer from the business logic layer. If I write more Django in the future I'll definitely be more aware of this but in many cases the framework (Templates, Forms, Models, Django-apps) don't really encourage this type of in-app architecture.

  • whalesalad 5 years ago

    Jinja is just as bad. They’re both a pain to extend.

    I believe firmly in separation of concerns but I have never understood the stubborn stance that there should be little to no logic inside of the template layer.

    ERB does it right. I have seen some heinous things there, don't get me wrong, but the freedom to use any part of Ruby is incredible.

    Nothing worse than when a client is hoping for a 1 hour fix on a really benign and silly bug - only to find that you'll need most of that time to whip up a custom template filter or tag, jumping through hoops to do all that.

  • jmconfuzeus 5 years ago

    This is one of the reasons why I'm moving to Rails. Frontend work is quite hard with templates and most of the community has moved towards Reactjs because of that, which I don't like.

    I think they designed it this way because they assumed that the backend and front developers would be different persons/teams, which makes sense for many projects but for me I'm just a solo dev trying to get work done as fast as possible.

    The way Rails does things with ERB makes total sense. DHH himself said that Rails was designed in a way that a single dev can take the framework and build something with it, no teams, no microservices, just plain Rails.

    ERB is more dangerous than Django Templates but I like it when a framework doesn't try to protect me from myself.

    • joelbluminator 5 years ago

      By what you're saying Rails is indeed gonna serve you well, that's exactly the use case where it shines: small teams that need to move fast. I also believe it's simple structure is quite good for big projects/teams as well but that's a different discussion.

  • collyw 5 years ago

    You can use different template engines fairly easily.

tootie 5 years ago

For those of you with a big portfolio of apps, how do you handle framework updates? Scheduled housekeeping once a quarter? Ad hoc? Ignore them until a disaster happens then panic?

  • collinmanderson 5 years ago

    I generally develop against django master with loud warnings. Whenever a warning comes up, such as `DEFAULT_AUTO_FIELD` not being specified, or a behavior change such as `SECURE_REFERRER_POLICY`, I go through and apply the same change to _all_ my projects at the same time.

    So I'm applying minor changes to multiple projects at the same time as I become aware of the new changes. Once the new Django version comes out, they're basically ready to go live with the new version.

  • frankwiles 5 years ago

    The necessary changes with your use of the framework are pretty minimal so it's easy enough to keep pace on about a quarterly basis.

    Usually the only friction is if there is a third party library/app you're using that doesn't yet support the newer version of Django.

tarequeh 5 years ago

Congratulations to the django team. Having used django for many of my projects for over a decade, it's exciting to see the django community is still going strong and the core members are continuing to push out significant releases such as the 3.2 LTS.

ghughes 5 years ago

Avoid for now if you use django-cachalot; one of the monkey patches is broken in Django 3.2.

itwy 5 years ago

I've been using Django since 2010, I recently hit a roadblock with it that forced me to switch to Go for one of my projects. That's to say, it's not for everything. Especially may not be suitable for advanced SaaS services.

NeutralForest 5 years ago

I haven't used Django except as an ORM and it was a terrible experience. Anytime I wanted to update an existing relationship, it was a pain. I've heard a lot of good stuff about it when used as a web framework but I was really baffled by the ORM.

  • ph4 5 years ago

    What was so painful about it? Unless you're making some really significant changes to your models, Django's migration commands handle 99.9% of cases including most common edge cases. I can't imagine it being any easier, and certainly haven't seen any other web frameworks handling migrations any better.

    • NeutralForest 5 years ago

      I just tried to add a new attribute to a many-to-many relationships

  • Syntaf 5 years ago

    I've found the Django ORM to be, in my own opinion, one of the easiest ORMs to hit the ground running with. What was the confusing aspect of updating relational data for you?

    • NeutralForest 5 years ago

      Creating relationships was not a problem but for example, adding new fields to an already created many-2-many was an issue. Changing migration scripts was also a hassle.

      • skrtskrt 5 years ago

        I have run into this exact problem. A many-to-many table had a business meaning, not just an "invisible" relationship. We wanted to put a model in front of it & add soft deletes and created-at/updated-at fields, at it was a mess of hoops and hacks to jump through.

        • rrmm 5 years ago

          Does this go easier in any other ORM/DBs that you might have used? Sounds like the semantics of the real-world stuff didn't quite match up to the DB semantics.

          • skrtskrt 5 years ago

            We rolled a simple repository pattern library that fit over the SQLAlchemy Table API (no ORM objects, only tables).

            Actually writing the the tables was very freeing, no more separation and surprises in the translation between a single model and the multiple tables it can create.

            For each new object, we wrote a SQLAlchemy Table object, a domain entity object, and optionally an adapter if you need to map field names between the two. The 300 lines of repo library code did the rest.

            A little boilerplate, but no need for a ton of impenetrable, hyper-dynamic ORM code.

            Alembic can autogenerate migrations from the SQLALchemy Table objects