Django: One ORM to rule all databases

2 hours ago 2

Comparing the Django ORM support across official database backends, so you don’t have to learn it the hard way.

© 2025 Paolo Melchiorre CC BY-SA “Weels Street Bridge over the Chicago Rive, framed by Chicago's skyline in the heart of downton (USA)”© 2025 Paolo Melchiorre CC BY-SA “Weels Street Bridge over the Chicago Rive, framed by Chicago's skyline in the heart of downton (USA)”
Community involvement (10 part series)
  1. My involvement in the Python community
  2. FLOSS and linguistic diversity
  3. My Django active developers Sprints proposal 🌅
  4. 2023 Python Software Foundation Board Nomination
  5. 2024 Django Software Foundation board nomination
  6. My Django roadmap ideas 💡
  7. 2025 Django Software Foundation board nomination
  8. Thoughts on my election as a DSF board member
  9. My first DSF board meeting
  10. Django: one ORM to rule all databases 💍

🌐 Introduction

Choosing the right database backend for your Django project can feel like picking the right Italian wine: lots of options, but not all pairings are equally delightful!

This article gives you a visual and practical comparison of the most important Django ORM features across the main built-in database backends: PostgreSQL, SQLite, MariaDB, MySQL, and Oracle.

The aim? To help you quickly see where each backend excels and where there’s room to grow. It’s also a gentle nudge for contributors, sponsors, and curious developers to help improve Django for everyone.

🏛️ Database comparison

A quick overview of the databases officially supported by Django helps set the stage: knowing their basic facts and differences makes it easier to understand why ORM feature support varies across backends.

The following table presents up-to-date information on the main facts for each database natively supported in the current stable release of Django.

DatabaseDeveloperReleasedLatest versionLast releaseLicenseMin. supported version
PostgreSQL 🐘PostgreSQL Global Dev Group19961809/2025PostgreSQL13
SQLite 🪶D. Richard Hipp20003.50.407/2025Public Domain3.31.0
MariaDB 🦭MariaDB Foundation200912.0.208/2025GPL v210.3
MySQL 🐬Oracle Corporation19959.407/2025GPL v28.0
Oracle 🔮Oracle Corporation197923ai09/2023Proprietary19c

Note: All data above refers to Django 5.2 LTS, which is the latest stable version at the time of publication (October 2025). Supported versions and latest releases may change in future Django releases—always check the official Django documentation for the most current information.

🌈 Inspiration

The matrix is inspired by Django’s GeoDjango compatibility tables, however, the GeoDjango table is updated by hand, so its accuracy depends on contributors keeping it current—making the process tiring and not always 100% reliable for users who need verified information.

🎯 Why this matrix?

This matrix’s aim is simple: help Django developers instantly understand which ORM features work with each official database backend—no more guessing, no more surprises!

I want to kickstart a community effort to create an official, always up-to-date and automatically generated matrix, making it easier for everyone to choose, plan, and contribute to Django’s future.

⚠️ Disclaimer

This comparison is illustrative only. I wrote it for community discussion and inspiration, not for production planning! Always check the official documentation for up-to-date info.

📊 Django ORM feature support table

This table shows (with illustrative data) which Django ORM features are supported or limited across the main database backends.

FeaturePostgreSQL 🐘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: Each symbol means Supported (✅), Partially Supported (⚠️), or Not Supported (🚫). Data are illustrative only.

👀 At-a-glance

Each bar shows how many features are fully supported (✅) out of 20 total. Data are illustrative only.

Django ORM Feature Support by BackendDatabaseSupported Features
PostgreSQL 🐘 20/20
SQLite 🪶 18/20
MariaDB 🦭 17/20
MySQL 🐬 17/20
Oracle 🔮 15/20

🤔 About this comparison

This table and its visualizations are illustrative only—provided as an example for discussion and inspiration. They do not exist as such in the official Django documentation (at least, not as of Django 5.2). It would be fantastic to have this kind of feature matrix auto-generated from the Django codebase itself whenever the docs are built. Django already tracks a lot of backend support internally, but creating a real, always-updated comparison is not easy.

“Wouldn’t it be great if this table was generated automatically and kept up to date?”

A quick check of other major ORM projects (like SQLAlchemy, Prisma, Hibernate, Eloquent ORM, ActiveRecord for Rails) shows that none of them currently offer such an exhaustive feature comparison matrix for their database backends. If Django’s documentation provided this, it would truly be a first and a big win for the open source world!

Full-text search is a great example of an ORM feature that isn’t available everywhere: right now, PostgreSQL is the only database backend that fully supports this feature in Django’s ORM. SQLite could potentially offer some form of full-text search, but Django’s ORM doesn’t currently support it.

Figuring out which databases support this feature (and to what extent) is far from straightforward; having a clear matrix or chart would make it much easier for users to discover what’s possible with their current database, choose a backend based on the features they need, or even encourage contributors and companies to fill in the gaps.

Here’s how you can use it in Django with PostgreSQL (see search lookup):

>>> Entry.objects.filter(body_text__search="Cheese") &LTQuerySet [&LTEntry: Cheese on Toast recipes>, &LTEntry: Pizza Recipes>]>

Want to go deeper? Check out my article “Full-text search in Django with PostgreSQL” for a practical deep dive into how to use this powerful feature!

🦉 History Bits

Some fun facts and milestones from the Django ORM journey:

Django got built-in migrations (inspired by Andrew Godwin’s South app) starting from version 1.7 in 2014—so from that moment, no more “pip install South” and no more migration headaches for Django devs everywhere. Thanks, Andrew!

✨ Idea spark

💡 Early inspiration

The idea for a Django ORM feature comparison table started during my first contribution to the Django ORM in version 2.0, at the DjangoCon Europe 2017 sprints. I added the RandomUUID function and the pgcrypto extension. I quickly noticed how hard it was to know which features each backend really supported—info was in the code, but not easy to find.

When working with GeoDjango, I found the (manually updated) compatibility tables for spatial features across databases. They were great for understanding support and for making charts for my articles and talks, even if they sometimes didn’t match the real code.

Later, when I worked on GeneratedField, it became clear that describing backend differences only in text wasn’t scalable. This was especially true when writing articles and preparing my DjangoCon US 2025 talk on GeneratedField.

At the last DjangoCon US 2025, I talked with other Django folks about backend support, especially for proprietary databases like Oracle. During a chat with Jeff Triplett, we agreed that real numbers about feature support would help get more support from companies and the community. That’s when the idea of a dynamic, code-driven comparison table came back to me.

During the sprint at DjangoCon US 2025, I mentioned this idea to Django Fellow Jacob Walls, and he seemed interested in the topic.

🚀 What’s next?

Tomorrow, in Palafrugell, Spain, we start “Django on the Med 🏖️” which I organized with Carlton Gibson, inspired by my “My Django active developers Sprints proposal”.

In one of our planning meetings, I pitched the comparison table to Carlton and got a positive response. So before the event kicks off, I’m sharing this article to spark discussion to start a conversation with all Django fans and the wider Python community.

🗣️ Call to action

Have feedback, corrections, or want to help create a real matrix? Reach out or comment in this forum thread!

🔗 References

Read Entire Article