ORM Party

CRUD

Select ORMs to compare

Pick one or more ORMs from the bar above

Insert One

SQL

INSERT INTO users (name, email)
VALUES ('Alice', 'alice@example.com');

Django ORM

user = User.objects.create(
    name="Alice",
    email="alice@example.com",
)

SQLAlchemy

with Session(engine) as session:
    user = User(name="Alice", email="alice@example.com")
    session.add(user)
    session.commit()

SQLModel

with Session(engine) as session:
    user = User(name="Alice", email="alice@example.com")
    session.add(user)
    session.commit()

Tortoise ORM

user = await User.create(
    name="Alice", email="alice@example.com"
)

Peewee

user = User.create(
    name="Alice",
    email="alice@example.com",
)

Prisma

const user = await prisma.user.create({
  data: {
    name: "Alice",
    email: "alice@example.com",
  },
});

Drizzle

await db.insert(users).values({
  name: "Alice",
  email: "alice@example.com",
});

Kysely

const user = await db
  .insertInto('users')
  .values({
    name: 'Alice',
    email: 'alice@example.com',
  })
  .returningAll()
  .executeTakeFirst()

TypeORM

const user = await userRepository.save({
  name: "Alice",
  email: "alice@example.com",
});

MikroORM

const em = orm.em.fork();

const user = em.create(User, {
  name: "Alice",
  email: "alice@example.com",
});
await em.persistAndFlush(user);

Sequelize

const user = await User.create({
  name: "Alice",
  email: "alice@example.com",
});

Insert Many (Bulk)

SQL

INSERT INTO users (name, email)
VALUES
  ('Alice', 'alice@example.com'),
  ('Bob', 'bob@example.com'),
  ('Charlie', 'charlie@example.com');

Django ORM

users = User.objects.bulk_create([
    User(name="Alice", email="alice@example.com"),
    User(name="Bob", email="bob@example.com"),
    User(name="Charlie", email="charlie@example.com"),
])

SQLAlchemy

with Session(engine) as session:
    session.add_all([
        User(name="Alice", email="alice@example.com"),
        User(name="Bob", email="bob@example.com"),
        User(name="Charlie", email="charlie@example.com"),
    ])
    session.commit()

SQLModel

with Session(engine) as session:
    session.add_all([
        User(name="Alice", email="alice@example.com"),
        User(name="Bob", email="bob@example.com"),
        User(name="Charlie", email="charlie@example.com"),
    ])
    session.commit()

Tortoise ORM

await User.bulk_create([
    User(name="Alice", email="alice@example.com"),
    User(name="Bob", email="bob@example.com"),
    User(name="Charlie", email="charlie@example.com"),
])

Peewee

User.insert_many([
    {"name": "Alice", "email": "alice@example.com"},
    {"name": "Bob", "email": "bob@example.com"},
    {"name": "Charlie", "email": "charlie@example.com"},
]).execute()

Prisma

const users = await prisma.user.createMany({
  data: [
    { name: "Alice", email: "alice@example.com" },
    { name: "Bob", email: "bob@example.com" },
    { name: "Charlie", email: "charlie@example.com" },
  ],
});

Drizzle

await db.insert(users).values([
  { name: "Alice", email: "alice@example.com" },
  { name: "Bob", email: "bob@example.com" },
  { name: "Charlie", email: "charlie@example.com" },
]);

Kysely

const users = await db
  .insertInto('users')
  .values([
    { name: 'Alice', email: 'alice@example.com' },
    { name: 'Bob', email: 'bob@example.com' },
    { name: 'Charlie', email: 'charlie@example.com' },
  ])
  .returningAll()
  .execute()

TypeORM

const users = await userRepository.save([
  { name: "Alice", email: "alice@example.com" },
  { name: "Bob", email: "bob@example.com" },
  { name: "Charlie", email: "charlie@example.com" },
]);

MikroORM

const em = orm.em.fork();

const users = em.create(User, [
  { name: "Alice", email: "alice@example.com" },
  { name: "Bob", email: "bob@example.com" },
  { name: "Charlie", email: "charlie@example.com" },
]);
await em.persistAndFlush(users);

Sequelize

const users = await User.bulkCreate([
  { name: "Alice", email: "alice@example.com" },
  { name: "Bob", email: "bob@example.com" },
  { name: "Charlie", email: "charlie@example.com" },
]);

Fetch by Primary Key

SQL

SELECT * FROM users WHERE id = 1;

Django ORM

user = User.objects.get(pk=1)

SQLAlchemy

with Session(engine) as session:
    user = session.get(User, 1)

SQLModel

with Session(engine) as session:
    user = session.get(User, 1)

Tortoise ORM

user = await User.get(id=1)

Peewee

user = User.get_by_id(1)

Prisma

const user = await prisma.user.findUnique({
  where: { id: 1 },
});

Drizzle

const user = await db.select()
  .from(users)
  .where(eq(users.id, 1));

Kysely

const user = await db
  .selectFrom('users')
  .selectAll()
  .where('id', '=', 1)
  .executeTakeFirst()

TypeORM

const user = await userRepository.findOneBy({ id: 1 });

MikroORM

const em = orm.em.fork();

const user = await em.findOne(User, { id: 1 });

Sequelize

const user = await User.findByPk(1);

Fetch First Match

SQL

SELECT * FROM users
WHERE name = 'Alice'
LIMIT 1;

Django ORM

user = User.objects.filter(name="Alice").first()

SQLAlchemy

with Session(engine) as session:
    user = session.execute(
        select(User).where(User.name == "Alice")
    ).scalars().first()

SQLModel

from sqlmodel import select

with Session(engine) as session:
    user = session.exec(
        select(User).where(User.name == "Alice")
    ).first()

Tortoise ORM

user = await User.filter(
    name="Alice"
).first()

Peewee

user = User.select().where(User.name == "Alice").first()

Prisma

const user = await prisma.user.findFirst({
  where: { name: "Alice" },
});

Drizzle

const user = await db.select()
  .from(users)
  .where(eq(users.name, "Alice"))
  .limit(1);

Kysely

const user = await db
  .selectFrom('users')
  .selectAll()
  .where('name', '=', 'Alice')
  .executeTakeFirst()

TypeORM

const user = await userRepository.findOneBy({ name: "Alice" });

MikroORM

const em = orm.em.fork();

const user = await em.findOne(User, { name: "Alice" });

Sequelize

const user = await User.findOne({
  where: { name: "Alice" },
});

Update One

SQL

UPDATE users
SET email = 'newalice@example.com'
WHERE id = 1;

Django ORM

user = User.objects.get(pk=1)
user.email = "newalice@example.com"
user.save()

SQLAlchemy

with Session(engine) as session:
    user = session.get(User, 1)
    user.email = "newalice@example.com"
    session.commit()

SQLModel

with Session(engine) as session:
    user = session.get(User, 1)
    user.email = "newalice@example.com"
    session.add(user)
    session.commit()

Tortoise ORM

user = await User.get(id=1)
user.email = "newalice@example.com"
await user.save()

Peewee

user = User.get_by_id(1)
user.email = "newalice@example.com"
user.save()

Prisma

const user = await prisma.user.update({
  where: { id: 1 },
  data: { email: "newalice@example.com" },
});

Drizzle

await db.update(users)
  .set({ email: "newalice@example.com" })
  .where(eq(users.id, 1));

Kysely

await db
  .updateTable('users')
  .set({ email: 'newalice@example.com' })
  .where('id', '=', 1)
  .executeTakeFirst()

TypeORM

await userRepository.update(1, {
  email: "newalice@example.com",
});

MikroORM

const em = orm.em.fork();

await em.nativeUpdate(User, { id: 1 }, {
  email: "newalice@example.com",
});

Sequelize

await User.update(
  { email: "newalice@example.com" },
  { where: { id: 1 } },
);

Update Many

SQL

UPDATE users
SET name = 'Alice Smith'
WHERE name = 'Alice';

Django ORM

User.objects.filter(name="Alice").update(name="Alice Smith")

SQLAlchemy

with Session(engine) as session:
    session.execute(
        update(User)
        .where(User.name == "Alice")
        .values(name="Alice Smith")
    )
    session.commit()

SQLModel

from sqlalchemy import update

with Session(engine) as session:
    session.exec(
        update(User)
        .where(User.name == "Alice")
        .values(name="Alice Smith")
    )
    session.commit()

Tortoise ORM

await User.filter(name="Alice").update(
    name="Alice Smith"
)

Peewee

User.update(name="Alice Smith").where(
    User.name == "Alice"
).execute()

Prisma

await prisma.user.updateMany({
  where: { name: "Alice" },
  data: { name: "Alice Smith" },
});

Drizzle

await db.update(users)
  .set({ name: "Alice Smith" })
  .where(eq(users.name, "Alice"));

Kysely

await db
  .updateTable('users')
  .set({ name: 'Alice Smith' })
  .where('name', '=', 'Alice')
  .execute()

TypeORM

await userRepository.update(
  { name: "Alice" },
  { name: "Alice Smith" },
);

MikroORM

const em = orm.em.fork();

await em.nativeUpdate(User, { name: "Alice" }, {
  name: "Alice Smith",
});

Sequelize

await User.update(
  { name: "Alice Smith" },
  { where: { name: "Alice" } },
);

Upsert

SQL

INSERT INTO users (name, email)
VALUES ('Alice Smith', 'alice@example.com')
ON CONFLICT (email)
DO UPDATE SET name = EXCLUDED.name;

Django ORM

user, created = User.objects.update_or_create(
    email="alice@example.com",
    defaults={"name": "Alice Smith"},
)

SQLAlchemy

from sqlalchemy.dialects.postgresql import insert

with Session(engine) as session:
    stmt = insert(User).values(
        name="Alice Smith", email="alice@example.com"
    ).on_conflict_do_update(
        index_elements=["email"],
        set_={"name": "Alice Smith"},
    )
    session.execute(stmt)
    session.commit()

SQLModel

from sqlalchemy.dialects.postgresql import insert

with Session(engine) as session:
    stmt = insert(User).values(
        name="Alice Smith", email="alice@example.com"
    ).on_conflict_do_update(
        index_elements=["email"],
        set_={"name": "Alice Smith"},
    )
    session.exec(stmt)
    session.commit()

Tortoise ORM

user, created = await User.update_or_create(
    email="alice@example.com",
    defaults={"name": "Alice Smith"},
)

Peewee

User.insert(
    name="Alice Smith",
    email="alice@example.com",
).on_conflict(
    conflict_target=[User.email],
    update={User.name: "Alice Smith"},
).execute()

Prisma

const user = await prisma.user.upsert({
  where: { email: "alice@example.com" },
  update: { name: "Alice Smith" },
  create: { name: "Alice Smith", email: "alice@example.com" },
});

Drizzle

await db.insert(users).values({
  name: "Alice Smith",
  email: "alice@example.com",
}).onConflictDoUpdate({
  target: users.email,
  set: { name: "Alice Smith" },
});

Kysely

await db
  .insertInto('users')
  .values({
    name: 'Alice Smith',
    email: 'alice@example.com',
  })
  .onConflict((oc) =>
    oc.column('email').doUpdateSet({ name: 'Alice Smith' })
  )
  .executeTakeFirst()

TypeORM

await userRepository.upsert(
  { name: "Alice Smith", email: "alice@example.com" },
  ["email"],
);

MikroORM

const em = orm.em.fork();

const user = await em.upsert(User, {
  name: "Alice Smith",
  email: "alice@example.com",
});

Sequelize

const [user, created] = await User.upsert({
  name: "Alice Smith",
  email: "alice@example.com",
});

Delete One

SQL

DELETE FROM users
WHERE id = 1;

Django ORM

User.objects.filter(pk=1).delete()

SQLAlchemy

with Session(engine) as session:
    user = session.get(User, 1)
    session.delete(user)
    session.commit()

SQLModel

with Session(engine) as session:
    user = session.get(User, 1)
    session.delete(user)
    session.commit()

Tortoise ORM

user = await User.get(id=1)
await user.delete()

Peewee

User.delete().where(User.id == 1).execute()

Prisma

await prisma.user.delete({
  where: { id: 1 },
});

Drizzle

await db.delete(users).where(eq(users.id, 1));

Kysely

await db
  .deleteFrom('users')
  .where('id', '=', 1)
  .executeTakeFirst()

TypeORM

await userRepository.delete(1);

MikroORM

const em = orm.em.fork();

await em.nativeDelete(User, { id: 1 });

Sequelize

await User.destroy({
  where: { id: 1 },
});

Delete Many

SQL

DELETE FROM users
WHERE email LIKE '%@old-domain.com';

Django ORM

User.objects.filter(email__endswith="@old-domain.com").delete()

SQLAlchemy

with Session(engine) as session:
    session.execute(
        delete(User).where(User.email.like("%@old-domain.com"))
    )
    session.commit()

SQLModel

from sqlalchemy import delete

with Session(engine) as session:
    session.exec(
        delete(User).where(User.email.endswith("@old-domain.com"))
    )
    session.commit()

Tortoise ORM

await User.filter(
    email__endswith="@old-domain.com"
).delete()

Peewee

User.delete().where(
    User.email.endswith("@old-domain.com")
).execute()

Prisma

await prisma.user.deleteMany({
  where: {
    email: { contains: "@old-domain.com" },
  },
});

Drizzle

await db.delete(users)
  .where(like(users.email, "%@old-domain.com"));

Kysely

await db
  .deleteFrom('users')
  .where('email', 'like', '%@old-domain.com')
  .execute()

TypeORM

await userRepository
  .createQueryBuilder()
  .delete()
  .from(User)
  .where("email LIKE :pattern", { pattern: "%@old-domain.com" })
  .execute();

MikroORM

const em = orm.em.fork();

await em.createQueryBuilder(User)
  .delete()
  .where({ email: { $like: "%@old-domain.com" } })
  .execute();

Sequelize

import { Op } from "sequelize";

await User.destroy({
  where: {
    email: { [Op.like]: "%@old-domain.com" },
  },
});

Atomic Increment

SQL

UPDATE users
SET views = views + 1
WHERE id = 1;

Django ORM

from django.db.models import F

User.objects.filter(id=1).update(
    views=F("views") + 1
)

SQLAlchemy

from sqlalchemy import update

stmt = (
    update(User)
    .where(User.id == 1)
    .values(views=User.views + 1)
)
session.execute(stmt)
session.commit()

SQLModel

from sqlalchemy import update

with Session(engine) as session:
    session.exec(
        update(User)
        .where(User.id == 1)
        .values(views=User.views + 1)
    )
    session.commit()

Tortoise ORM

from tortoise.expressions import F

await User.filter(id=1).update(
    views=F("views") + 1
)

Peewee

User.update(
    views=User.views + 1
).where(User.id == 1).execute()

Prisma

await prisma.user.update({
  where: { id: 1 },
  data: {
    views: { increment: 1 },
  },
});

Drizzle

import { eq, sql } from "drizzle-orm";

await db
  .update(users)
  .set({ views: sql`${users.views} + 1` })
  .where(eq(users.id, 1));

Kysely

import { sql } from 'kysely'

await db
  .updateTable('users')
  .set({ views: sql<number>`views + 1` })
  .where('id', '=', 1)
  .executeTakeFirst()

TypeORM

await dataSource
  .getRepository(User)
  .increment({ id: 1 }, "views", 1);

MikroORM

import { raw } from "@mikro-orm/core";

const em = orm.em.fork();

await em.nativeUpdate(User, { id: 1 }, {
  views: raw("views + 1"),
});

Sequelize

await User.increment("views", {
  by: 1,
  where: { id: 1 },
});