Agent Wranglers

Recommended Open source

Use a mature ORM for database code

Write database code with Prisma in TypeScript and SQLAlchemy in Python, or with the Django ORM inside a Django project. Keep one ORM per codebase.

Cost

Open source. Prisma is Apache-2.0, SQLAlchemy is MIT and Django is BSD-3-Clause. Prisma also sells paid hosted add-ons, which the ORM does not need.

How to do it

Prisma 2.0.0 was published on 9 June 2020, and 7.10.1 on 15 October 2026. Its client has about 11.1 million weekly npm downloads, under Apache-2.0. SQLAlchemy 1.0.0 came out on 16 April 2015, and 2.1.5 on 16 October 2026. It has about 87.6 million weekly PyPI downloads, under the MIT licence. Django 6.1.2 came out on 6 October 2026, and the 5.2 LTS line has fixes until April 2028. All three generate parameterised SQL, which closes the hole Pass values as parameters describes. Load related rows in one query, as Load related rows in one query says. Drizzle has more weekly downloads than Prisma, about 18.3 million, but it is still before 1.0, at 0.45.4. Choose something else when the team wants SQL-shaped queries in TypeScript, and pick Drizzle once 1.0 ships.

Examples

Using these examples: they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

TypeScript example

import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();
const orders = await prisma.order.findMany({
  where: { customerId, status: 'paid' },
  include: { lines: true },
  orderBy: { createdAt: 'desc' },
  take: 20,
});

Python example

from sqlalchemy import select
from sqlalchemy.orm import Session, selectinload

PAGE_SIZE = 20

def paid_orders(session: Session, customer_id: int) -> list[Order]:
    query = (select(Order)
             .where(Order.customer_id == customer_id, Order.status == "paid")
             .options(selectinload(Order.lines))
             .order_by(Order.created_at.desc())
             .limit(PAGE_SIZE))
    return list(session.scalars(query))

How to check

The dependency list holds exactly one of @prisma/client, drizzle-orm, typeorm, sequelize, sqlalchemy or the Django ORM. No source file builds SQL by joining strings with user input.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/stack/databases-and-storage/orm">Agent Wranglers software choices playbook</a>. In code you write, add a comment next to it with the same link.