PageSourceSearch

https://rebelion.la/assets/js/d238e77e.b4082abd.js

js rebelion.la collected 2026-09-25 22:27:21 UTC 13,954 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkla_rebelion_blog=self.webpackChunkla_rebelion_blog||[]).push([["1241"],{25904(e,i,n){n.r(i),n.d(i,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>l,metadata:()=>t,toc:()=>d});var t=n(59624),s=n(74848),r=n(28453);let l={title:"Are ORMs Still Relevant in the AI Copilot Era?",description:"With AI copilots generating code faster than ever, do we still need ORMs? Explore the tradeoffs between productivity and semantic clarity, and how to use both effectively in 2026.",authors:["adrianescutia"],tags:["ai","engineering","debugging"],keywords:["AI","ORMs","Drizzle","SQL","debugging","production incidents","software architecture"],date:new Date("2026-05-30T12:00:00.000Z"),image:"/img/blog/are-orms-still-relevant-and-useful.png"},a,o={authorsImageUrls:[void 0]},d=[{value:"The Incident (Anonymized)",id:"the-incident-anonymized",level:2},{value:"Was Drizzle "Hiding" the Bug?",id:"was-drizzle-hiding-the-bug",level:2},{value:"Why This Matters More in the AI Era",id:"why-this-matters-more-in-the-ai-era",level:2},{value:"Are ORMs Still Useful?",id:"are-orms-still-useful",level:2},{value:"Where ORMs Hurt (and AI Can Make It Worse)",id:"where-orms-hurt-and-ai-can-make-it-worse",level:2},{value:"A Practical Pattern That Worked for Us",id:"a-practical-pattern-that-worked-for-us",level:2},{value:"A Better Rule for 2026",id:"a-better-rule-for-2026",level:2},{value:"Checklist: Keep ORMs, Avoid Blind Spots",id:"checklist-keep-orms-avoid-blind-spots",level:2},{value:"Final Take",id:"final-take",level:2}];function c(e){let i={em:"em",h2:"h2",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(i.p,{children:["AI copilots can scaffold full-stack apps in minutes, write migrations, generate APIs, and even propose query optimizations. So the obvious question is: ",(0,s.jsx)(i.strong,{children:"If AI can write SQL directly, do we still need ORMs?"})]}),"\n",(0,s.jsx)(i.p,{children:"After a painful production incident this week, my answer is:"}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.strong,{children:"Yes, ORMs still matter. But blind trust in abstractions does not."})}),"\n",(0,s.jsx)(i.h2,{id:"the-incident-anonymized",children:"The Incident (Anonymized)"}),"\n",(0,s.jsx)(i.p,{children:"A customer flow in production kept returning a business-rule conflict. The strange part:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"The customer looked eligible in an internal troubleshooting tool."}),"\n",(0,s.jsx)(i.li,{children:"The same customer looked ineligible in the portal transaction flow."}),"\n",(0,s.jsx)(i.li,{children:"Verification data was valid."}),"\n",(0,s.jsx)(i.li,{children:"Branch resolution looked valid."}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["Everything ",(0,s.jsx)(i.em,{children:"looked"})," correct, yet the live flow still failed."]}),"\n",(0,s.jsx)(i.p,{children:"We chased auth freshness, payload format, environment flags, and campaign config. Useful, but not the root cause."}),"\n",(0,s.jsx)(i.p,{children:"The real issue was subtler:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"The troubleshooting tool used a direct SQL path."}),"\n",(0,s.jsx)(i.li,{children:"The transaction flow used ORM-composed queries."}),"\n",(0,s.jsx)(i.li,{children:"Those two paths were logically intended to be equivalent."}),"\n",(0,s.jsx)(i.li,{children:"In practice, they were not equivalent under real production data."}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:'This was not "SQL bad, ORM good" or "ORM bad, SQL good."'}),"\n",(0,s.jsxs)(i.p,{children:["It was ",(0,s.jsx)(i.strong,{children:"equivalence drift"})," between two query construction styles."]}),"\n",(0,s.jsx)(i.h2,{id:"was-drizzle-hiding-the-bug",children:'Was Drizzle "Hiding" the Bug?'}),"\n",(0,s.jsxs)(i.p,{children:["Short answer: ",(0,s.jsx)(i.strong,{children:"partly yes, in the same way any abstraction can hide behavior"}),"."]}),"\n",(0,s.jsx)(i.p,{children:"Longer answer:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"We assumed the ORM-generated query semantics matched the SQL semantics we had in mind."}
1),"\n",(0,s.jsx)(i.li,{children:"We did not validate that assumption early enough against production-like conditions."}),"\n",(0,s.jsx)(i.li,{children:'The troubleshooting endpoint, built with explicit SQL, became the "truth probe" that exposed the mismatch.'}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"So it wasn\u2019t that the ORM was broken by definition. It was that abstraction reduced visibility right when we needed semantic certainty."}),"\n",(0,s.jsxs)(i.p,{children:["That can happen with ",(0,s.jsx)(i.strong,{children:"any"})," ORM, not just Drizzle."]}),"\n",(0,s.jsx)(i.h2,{id:"why-this-matters-more-in-the-ai-era",children:"Why This Matters More in the AI Era"}),"\n",(0,s.jsx)(i.p,{children:"AI accelerates implementation dramatically, but it also amplifies an old engineering risk:"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.strong,{children:"fast confidence in unverified assumptions"}),"."]}),"\n",(0,s.jsx)(i.p,{children:"When AI writes ORM-based code quickly, we often get:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"Clean types"}),"\n",(0,s.jsx)(i.li,{children:"Passing local tests"}),"\n",(0,s.jsx)(i.li,{children:"Readable service methods"}),"\n",(0,s.jsx)(i.li,{children:"Seemingly correct business logic"}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"But we still need to ask:"}),"\n",(0,s.jsxs)(i.ol,{children:["\n",(0,s.jsx)(i.li,{children:"Does this query shape produce the same rows as the intended SQL?"}),"\n",(0,s.jsx)(i.li,{children:"Does it stay equivalent when data cardinality and relationships change?"}),"\n",(0,s.jsx)(i.li,{children:"Are we debugging behavior, or abstractions of behavior?"}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["AI makes code generation cheap. It does ",(0,s.jsx)(i.strong,{children:"not"})," make semantic verification optional."]}),"\n",(0,s.jsx)(i.h2,{id:"are-orms-still-useful",children:"Are ORMs Still Useful?"}),"\n",(0,s.jsx)(i.p,{children:"Absolutely. ORMs still provide massive value:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.strong,{children:"Productivity"}),": less repetitive CRUD and mapping boilerplate."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.strong,{children:"Safety by default"}),": parameterized queries and fewer injection footguns."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.strong,{children:"Schema ergonomics"}),": typed models and centralized constraints."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.strong,{children:"Relationship handling"}),": cleaner expression of common joins and associations."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.strong,{children:"Team readability"}),": business logic can be easier to follow in service code than in raw SQL blocks."]}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"These benefits did not disappear because AI got better."}),"\n",(0,s.jsx)(i.h2,{id:"where-orms-hurt-and-ai-can-make-it-worse",children:"Where ORMs Hurt (and AI Can Make It Worse)"}),"\n",(0,s.jsx)(i.p,{children:"In critical flows, the pain points become obvious fast:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"Implicit query semantics are harder to reason about during incidents."}),"\n",(0,s.jsx)(i.li,{children:"Composition patterns can diverge from your mental SQL model."}),"\n",(0,s.jsx)(i.li,{children:'Debugging becomes "inspect builder state" instead of "read exact query intent."'}),"\n",(0,s.jsx)(i.li,{children:"AI-generated abstractions can look right while still being semantically off."}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"So the core tradeoff remains:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.strong,{children:"ORMs optimize developer throughput."})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.strong,{children:"Direct SQL optimizes semantic explicitness."})}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"The trick is not choosing one forever. The trick is choosing the right abstraction level per path."}),"\n",(0,s.jsx)(i.h2,{id:"a-practical-pattern-that-worked-for-us",children:"A Practical Pattern That Worked for Us"}),"\n",(0,s.jsx)(i.p,{children:"What saved us was not a heroic guess. It was architecture and observability:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"We had a troubleshooting path using explicit SQL."}),"\n",(0,s.jsx)(i.li,{children:"It provided deterministic visibility into eligibility decisions."}),"\n",(0,s.jsx)(i.li,{children:"We compared ORM-driven and SQL-driven outcomes on the same input."}),"\n",(0,s.jsx)(i.li,{children:"We aligned the production query shape to the proven SQL semantics."}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["In other words, we used a ",(0,s.jsx)(i.strong,{children:"dual-lens strategy"}),":"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"ORM for day-to-day velocity."}),"\n",(0,s.jsx)(i.li,{children:"Explicit SQL for observability and critical decision points."}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"That combination reduced ambiguity fast."}),"\n",(0,s.jsx)(i.h2,{id:"a-better-rule-for-2026",children:"A Better Rule for 2026"}),"\n",(0,s.jsx)(i.p,{children:'Instead of "ORM vs SQL," use this operating rule:'}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.strong,{children:"Use ORMs by default. Require SQL-level validation for high-impact business decisions."})}),"\n",(0,s.jsx)(i.p,{children:"Examples of high-impact paths:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"Eligibility and pricing decisions."}),"\n",(0,s.jsx)(i.li,{children:"Financial calculations."}),"\n",(0,s.jsx)(i.li,{children:"Permission and access checks."}),"\n",(0,s.jsx)(i.li,{children:"Deduplication and idempotency logic."}),"\n",(0,s.jsx)(i.li,{children:"Anything that can produce customer-facing conflicts at scale."}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"checklist-keep-orms-avoid-blind-spots",children:"Checklist: Keep ORMs, Avoid Blind Spots"}),"\n",(0,s.jsxs)(i.ol,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.strong,{children:"Log decision inputs and outputs"})," (not just errors)."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.strong,{children:"Mirror one critical query path in explicit SQL"})," for diagnostics."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.strong,{children:"Test semantic equivalence"})," between ORM and SQL for edge cases."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.strong,{children:"Treat generated query shape as part of behavior"}),", not an implementation detail."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.strong,{children:"Use AI to draft queries, then verify with production-like data"})," before trusting conclusions."]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"final-take",children:"Final Take"}),"\n",(0,s.jsx)(i.p,{children:"AI copilots did not make ORMs obsolete."}),"\n",(0,s.jsxs)(i.p,{children:["They made one thing more important: ",(0,s.jsx)(i.strong,{children:"verification discipline"}),"."]}),"\n",(0,s.jsx)(i.p,{children:"ORMs are still excellent tools for human teams. But with AI accelerating output, we should stop treating ORM-generated behavior as automatically correct in critical paths."}),"\n",(0,s.jsx)(i.p,{children:"Keep the abstraction. Add a truth probe."}),"\n",(0,s.jsx)(i.p,{children:"That one shift can save days of production back-and-forth."})]})}function h(e={}){let{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453(e,i,n){n.d(i,{R:()=>l,x:()=>a});var t=n(96540);let s={},r=t.createContext(s);function l(e){let i=t.useContext(r);return t.useMemo(function(){return"function"==typeof e?e(i):{...i,...e}},[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),t.createElement(r.Provider,{value:i},e.children)}},59624(e){e.exports=JSON.parse('{"permalink":"/ai/are-orm-still-relevant-and-useful","source":"@site/blog/ai/are-orm-still-relevant-and-useful.md","title":"Are ORMs Still Relevant in the AI Copilot Era?","description":"With AI copilots generating code faster than ever, do we still need ORMs? Explore the tradeoffs between productivity and semantic clarity, and how to use both effectively in 2026.","date":"2026-05-30T12:00:00.000Z","tags":[{"inline":true,"label":"ai","permalink":"/tags/ai"},{"inline":true,"label":"engineering","permalink":"/tags/engineering"},{"inline":true,"label":"debugging","permalink":"/tags/debugging"}],"readingTime":4.01,"hasTruncateMarker":false,"authors":[{"name":"Adrian Escutia","title":"Founder, La Rebelion Labs","url":"https://www.linkedin.com/in/adrianescutia/","page":{"permalink":"/authors/authors/adrian-e
1scutia"},"socials":{"github":"https://github.com/la-rebelion","linkedin":"https://www.linkedin.com/in/adrianescutia/","x":"https://twitter.com/LaRebelionLabs","youtube":"https://www.youtube.com/@LaRebelion"},"imageURL":"/img/brand/logo-mark.png","key":"adrianescutia"}],"frontMatter":{"title":"Are ORMs Still Relevant in the AI Copilot Era?","description":"With AI copilots generating code faster than ever, do we still need ORMs? Explore the tradeoffs between productivity and semantic clarity, and how to use both effectively in 2026.","authors":["adrianescutia"],"tags":["ai","engineering","debugging"],"keywords":["AI","ORMs","Drizzle","SQL","debugging","production incidents","software architecture"],"date":"2026-05-30T12:00:00.000Z","image":"/img/blog/are-orms-still-relevant-and-useful.png"},"unlisted":false,"prevItem":{"title":"Models Are Becoming Commodities, Orchestration Is the New Advantage","permalink":"/ai/ai-models-are-becoming-commodities"},"nextItem":{"title":"How to Design Truth-Probe Troubleshooting Endpoints for AI-Generated Backends","permalink":"/how-to-design-truth-probe-troubleshooting-endpoints"}}')}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.