Community involvement (10 part series)
- My involvement in the Python community
- FLOSS and linguistic diversity
- My Django active developers Sprints proposal 🌅
- 2023 Python Software Foundation Board Nomination
- 2024 Django Software Foundation board nomination
- My Django roadmap ideas 💡
- 2025 Django Software Foundation board nomination
- Thoughts on my election as a DSF board member
- My first DSF board meeting
- Django: one ORM to rule all databases 💍
Introduction
Choosing the right database backend for a Django project can sometimes feel a bit confusing. There are many options, and each one has different features and limitations.
In this article, I want to give a clear and practical comparison of the main Django ORM features across the main native database backends: PostgreSQL, SQLite, MariaDB, MySQL, and Oracle.
My goal is to help you see quickly where each database works well and where it has some limits. I also hope this can be useful for anyone who wants to improve Django, or just understand it better.
Supported databases
Here is a short overview of the databases that Django officially supports. Knowing some basic facts about them can help us understand why different features are available (or not) in the ORM.
The table below shows the most recent information for each database included in the latest Django stable release.
| Database | Developer | Released | Latest version | Last release | License | Min. supported version |
|---|---|---|---|---|---|---|
| PostgreSQL 🐘 | PostgreSQL Global Dev Group | 1996 | 18 | 09/2025 | PostgreSQL | 13 |
| SQLite 🪶 | D. Richard Hipp | 2000 | 3.50.4 | 07/2025 | Public Domain | 3.31.0 |
| MariaDB 🦭 | MariaDB Foundation | 2009 | 12.0.2 | 08/2025 | GPL v2 | 10.3 |
| MySQL 🐬 | Oracle Corporation | 1995 | 9.4 | 07/2025 | GPL v2 | 8.0 |
| Oracle 🔮 | Oracle Corporation | 1979 | 23ai | 09/2023 | Proprietary | 19c |
Note: All data refers to Django 5.2 LTS (October 2025). Supported versions and latest releases may change in future Django versions. Please check the official Django documentation for the most updated information.
Inspiration
This matrix is inspired by the GeoDjango compatibility tables in the Django documentation. Those tables are updated manually, so their accuracy depends on the effort of contributors. This makes it hard to be sure the information is always correct and up to date.
Matrix purpose
The purpose of this matrix is simple: to help Django users understand, at a glance, which ORM features are available for each official database backend. No more guessing or reading long documentation just to check if a feature is supported.
I also hope this can be a starting point for a community project: maybe one day Django will provide an updated, automatic matrix like this in the official docs.
Disclaimer
⚠️ The data in the table below is entirely fictional and intentionally provided only for example! ⚠️ I included these features just to show what the final matrix could look like, to help start a discussion in the community. Do not use them for any real analysis or decisions.
Feature matrix
This table shows, just as an example, which Django ORM features are supported or limited for each main database backend.
| Feature | PostgreSQL 🐘 | SQLite 🪶 | MariaDB 🦭 | MySQL 🐬 | Oracle 🔮 |
|---|---|---|---|---|---|
| Model Field Types & Constraints | |||||
| AutoField / BigAutoField | ✅ | ✅ | ✅ | ✅ | ✅ |
| BooleanField | ✅ | ✅ | ✅ | ✅ | ✅ |
| JSONField | ✅ | ⚠️ | ⚠️ | ⚠️ | 🚫 |
| ArrayField | ✅ | 🚫 | 🚫 | 🚫 | 🚫 |
| UniqueConstraint | ✅ | ✅ | ✅ | ✅ | ⚠️ |
| CheckConstraint | ✅ | ⚠️ | ✅ | ✅ | ✅ |
| Advanced Query Features | |||||
| Full-text Search | ✅ | ⚠️ | ⚠️ | ⚠️ | 🚫 |
| Window Functions | ✅ | ⚠️ | ✅ | ✅ | ⚠️ |
| F() Expressions | ✅ | ✅ | ✅ | ✅ | ✅ |
| Subquery & OuterRef | ✅ | ✅ | ✅ | ✅ | ⚠️ |
| SelectForUpdate | ✅ | 🚫 | ✅ | ⚠️ | 🚫 |
| Transactions & Integrity | |||||
| Atomic Transactions | ✅ | ⚠️ | ✅ | ✅ | ⚠️ |
| Savepoints | ✅ | 🚫 | ✅ | ✅ | ✅ |
| Serializable Isolation | ✅ | 🚫 | ⚠️ | ⚠️ | ✅ |
| Referential Integrity | ✅ | ⚠️ | ✅ | ✅ | ✅ |
| Spatial & GIS Features | |||||
| GeometryField | ✅ | ✅ | 🚫 | 🚫 | ✅ |
| Distance Queries | ✅ | ✅ | 🚫 | 🚫 | ⚠️ |
| RasterField | ✅ | 🚫 | 🚫 | 🚫 | 🚫 |
| Topology Support | ⚠️ | 🚫 | 🚫 | 🚫 | 🚫 |
Legend: Supported (✅), Partially Supported (⚠️), or Not Supported (🚫). Data is just for illustration.
Visual summary
Here’s a quick visual summary of how many features are fully supported (✅) out of 20 total for each database backend. The data is only for example.
| Database | Supported Features |
|---|---|
| PostgreSQL 🐘 | 19/20 |
| SQLite 🪶 | 13/20 |
| MariaDB 🦭 | 14/20 |
| MySQL 🐬 | 14/20 |
| Oracle 🔮 | 13/20 |
About this matrix
This table and the charts are only examples, for discussion and ideas. They are not in the official Django docs (at least, not in Django 5.2). It would be nice to have this feature matrix generated directly from the Django code, so it is always updated. Django already has a lot of information about backend support inside its code, but making a real and reliable comparison is not so simple.
“Wouldn’t it be great if this table was generated automatically and kept up to date?”
If you check other big ORM projects like SQLAlchemy, Prisma, Hibernate, Eloquent ORM, or ActiveRecord for Rails, you will see that none of them has a complete comparison matrix like this. If Django could offer it, it would be a great help for everyone who uses open source tools.
Feature example: full-text search
Full-text search is a good example of a feature that is not available everywhere. Right now, PostgreSQL is the only database backend that fully supports this feature in Django’s ORM. SQLite could, in theory, offer some kind of full-text search, but Django’s ORM does not support it.
It is not so easy to find out which database supports this feature and in what way. Having a clear matrix or chart would help users see what their current database can do, decide if they need to choose a different backend for more features, or help contributors and companies notice missing support and maybe work to add it.
Here’s how you can use it in Django with PostgreSQL (see search lookup):
>>> Entry.objects.filter(body_text__search="Cheese")
<QuerySet [<Entry: Cheese on Toast recipes>, <Entry: Pizza Recipes>]>
If you want to know more, you can read my article “Full-text search in Django with PostgreSQL” where I explain how to use this feature.
History facts
Django got integrated migrations (thanks to Andrew Godwin’s South app) starting with version 1.7 in 2014. From then on, developers did not need to use South for migrations anymore.
Idea origin
Early inspiration
The idea for a Django ORM comparison table started with my first contribution to the Django ORM in version 2.0, during the DjangoCon Europe 2017 sprints. I added the RandomUUID function and the pgcrypto extension. I noticed it was not easy to know which features were really supported by each backend, the information was in the code, but not simple to find.
When using GeoDjango, I saw the compatibility tables for spatial features. They were helpful for understanding support and making slides for articles and talks, even if sometimes they were not up to date with the code.
Later, when I worked on GeneratedField, I understood that describing backend differences only in the text was not scalable. This was even more clear when writing articles and preparing my DjangoCon US 2025 talk on GeneratedField.
At the last DjangoCon US 2025, I spoke with other Django developers about backend support, especially for databases like Oracle. In a chat with Jeff Triplett, we agreed that having real numbers about feature support could help get more help from companies and the community. That’s when the idea of a code based comparison table came back to me.
During the sprint at DjangoCon US 2025, I talked about this idea with Django Fellow Jacob Walls, and he found it interesting.
Next steps
Tomorrow in Palafrugell, Spain, we start “Django on the Med”, an event I organized with Carlton Gibson, inspired by my “My Django active developers Sprints proposal”.
In one of our meetings, I proposed the comparison table idea to Carlton, and he liked it. So, before the event starts, I am sharing this article to start a conversation with all Django fans and the Python community.
Join the discussion
If you have feedback, corrections, or want to help create a real matrix, please write or comment in this forum thread: