Should We Still Use ORMs When AI Writes the Code?
AI can write SQL instantly, so do applications still need ORMs? A practical guide to choosing ORM, raw SQL, or both.
AI can write a twelve-table SQL query before most of us have finished spelling “denormalization.”
It can generate migrations, explain execution plans, convert a Prisma query to PostgreSQL, and politely apologize after inventing a column that has never existed.
So it is reasonable to ask: Do we still need Object-Relational Mappers when AI can write the SQL for us?
The short answer is yes.
The more useful answer is: use an ORM for consistency, not as protection from SQL—and use AI for acceleration, not as protection from thinking.
AI changes the cost of producing database code. It does not change the cost of running the wrong query in production.
The original promise of the ORM
ORMs were never only about avoiding SQL.
They gave application teams a shared data-access vocabulary:
- models that map to domain concepts;
- parameterized queries by default;
- migrations tracked alongside code;
- relationships expressed consistently;
- transactions managed through one interface;
- reusable validation and lifecycle hooks;
- database access that fits the application’s type system.
That is valuable even if everyone on the team writes excellent SQL.
Consider a routine operation:
user = (
session.query(User)
.filter(User.email == email)
.one_or_none()
)
An AI assistant can produce the equivalent SQL immediately:
SELECT *
FROM users
WHERE email = :email;
But generating those six lines was never the expensive part.
The expensive part is deciding what “one user” means, whether deleted accounts count, which tenant owns the row, whether the result may be cached, how authorization is enforced, and what happens when two records somehow share the same email.
An ORM does not answer those questions. Raw SQL does not answer them either.
Architecture does.
AI makes syntax cheap, not consequences
Before coding assistants, one argument for ORMs was developer productivity. Most engineers could write a model query faster than they could recall every join, placeholder, and dialect-specific clause.
AI weakens that argument. Syntax recall is nearly free now.
However, database correctness depends on much more than syntax:
- cardinality;
- isolation levels;
- lock behavior;
- index selection;
- query plans;
- network round trips;
- transaction boundaries;
- data ownership;
- schema evolution.
AI can explain all of these. It can also misunderstand all of these while sounding like the colleague who has already checked.
The dangerous AI-generated query is rarely the one with invalid SQL. Invalid SQL fails quickly. The dangerous query is valid, passes the happy-path test, and quietly scans 80 million rows every Tuesday.
Removing the ORM does not remove abstraction. It replaces a visible, shared abstraction with thousands of individually generated decisions.
Where AI makes ORMs better
AI and ORMs are surprisingly good partners when the boundary is clear.
Faster routine work
Models, migrations, repositories, fixtures, and straightforward CRUD endpoints are structured tasks. AI handles them well, and the ORM gives the generated code a predictable target.
Instead of asking a model to invent a data-access style for every feature, the team can say:
Use the existing SQLAlchemy repository pattern. Preserve tenant filtering. Add a migration and focused tests.
Constraints improve generated code. A mature ORM setup supplies many constraints automatically.
Easier review
Reviewers already know what a normal query looks like in the chosen framework. Unexpected eager loading, a missing filter, or an accidental cascade stands out.
If every AI-generated feature uses a different combination of raw SQL, query builders, stored procedures, and vibes, review becomes an archaeological expedition.
Safer composition
Parameterized queries, typed models, reusable scopes, and transaction helpers reduce opportunities for generated code to make basic security mistakes.
This does not make ORM code secure by default. Raw query escape hatches, unsafe interpolation, mass assignment, and missing authorization checks still exist. It does mean the safest path can also be the easiest path.
Better context for the model
An ORM schema is machine-readable documentation.
Models expose names, types, relationships, constraints, and conventions in a form coding assistants can inspect. That context often produces more reliable output than a prompt describing the database from memory.
Where AI makes ORMs more dangerous
There is another side.
AI can produce ORM code so fluently that weak data access looks polished.
The N+1 query, now at machine speed
A generated loop may access a lazy-loaded relationship once per row. The endpoint works perfectly with five test records and performs a small denial-of-service attack on its own database with fifty thousand.
for order in orders:
print(order.customer.name)
The code looks harmless. The query log may tell a horror story.
Abstractions hide database-specific power
PostgreSQL window functions, partial indexes, EXPLAIN ANALYZE, recursive CTEs, row-level locking, JSON operators, and conflict handling are not implementation trivia. Sometimes they are the cleanest way to express the problem.
Forcing every query through the ORM can turn one precise statement into an unreadable object graph—or several round trips.
AI makes writing advanced SQL easier. That is a reason to use the escape hatch confidently, not to demolish the house.
Generated migrations deserve suspicion
A migration that adds a non-null column to a large table, rewrites every row, or holds a lock for too long can be syntactically perfect and operationally catastrophic.
Never approve a migration because the model called it “safe.”
Ask:
- Will it lock the table?
- Does it rewrite existing rows?
- Can old and new application versions run during deployment?
- Is there a rollback—or at least a roll-forward plan?
- How long will it take with production-sized data?
AI can help investigate these questions. It cannot accept the pager notification for you.
The false choice: ORM or raw SQL
Healthy systems often use both.
Use the ORM for:
- ordinary create, read, update, and delete operations;
- domain entities and relationships;
- standard filtering and pagination;
- migrations and schema history;
- transaction management;
- consistent tenant and soft-delete rules.
Use explicit SQL or a lower-level query builder for:
- reporting and analytical queries;
- performance-critical paths;
- bulk updates and imports;
- complex joins or window functions;
- database-specific features;
- queries whose execution plan is part of the design.
The key is to make the boundary intentional.
Keep raw SQL in named modules or repositories. Parameterize it. Test it against the real database engine. Document why the ORM version was insufficient. Observe it in production.
“The AI generated it” is not an architectural boundary.
A practical decision test
Before choosing the data-access approach for a feature, ask five questions.
1. Is this query ordinary?
If it retrieves or changes a small number of domain records through familiar relationships, start with the ORM.
2. Can the team predict the generated SQL?
If nobody reviewing the code can explain roughly what reaches the database, stop. Inspect the query log or generated statement before merging.
3. Does performance depend on the exact query plan?
When join order, indexes, locks, or aggregation strategy matter, make the SQL visible and test the plan with realistic data.
4. Are database-specific features the clearest solution?
Portability is useful only when there is a realistic chance of moving databases. Do not replace one excellent PostgreSQL query with forty lines of portable confusion to prepare for a migration nobody plans to perform.
5. Who owns this code after generation?
If the answer is “the AI,” the feature is not ready.
Someone on the team must understand the query, its failure modes, and its operational cost.
How to use AI without outsourcing database judgment
AI is most useful when asked to expose uncertainty, not hide it.
Try prompts like:
- “Show the SQL this ORM query is likely to generate.”
- “Identify possible N+1 queries and unnecessary round trips.”
- “What indexes would support this access pattern, and what are their write costs?”
- “Generate production-scale test data for this query.”
- “Compare the ORM and raw SQL versions for readability and performance.”
- “Review this migration for locking and backward-compatibility risks.”
- “What evidence would prove this query is safe under expected load?”
Then verify the answers with query logs, database documentation, tests, and execution plans.
The goal is not to make AI decide. The goal is to make good decisions cheaper.
So, should you use an ORM?
For most product applications: yes, as the default—not as a religion.
An ORM gives humans and AI a consistent structure for routine data access. It reduces accidental variation, makes common operations easier to review, and keeps schema changes connected to application code.
But every engineer working with one should still understand SQL, transactions, indexes, and query plans. Teams should have a respected path to raw SQL when the problem demands it.
AI has not made ORMs obsolete.
It has made blind abstraction more tempting.
Keep the ORM. Keep the escape hatch. Keep reading the SQL.
And when the coding assistant says the query is “highly optimized,” that is your cue to open EXPLAIN ANALYZE.