Understand PrismaPrisma & Traditional ORMs

Prisma & TypeORM

Learn how Prisma compares to TypeORM

Reading data

Fetching single objects

TypeORM

const userRepository = getRepository(User)
const user = await userRepository.findOne(id)

Prisma

const user = await prisma.user({ id })

Fetching selected scalars of single objects

TypeORM

const userRepository = getRepository(User)
const user = await userRepository.findOne(id, {
  select: ['id', 'email'],
})

Prisma

const userFragment = await prisma.user({ id }).$fragment(`
  fragment NameAndEmail on User { id email }`
`)

Fetching relations

TypeORM

Using `relations`
Using JOIN
Eager relations
const userRepository = getRepository(User)
const user = await userRepository.findOne(id, {
  relations: ['posts'],
})
Copy

Prisma

Fluent API
Using fragments
Native GraphQL
const postsByUser = await prisma.user({ id }).posts()
Copy

Filtering for concrete values

TypeORM

const userRepository = getRepository(User)
const users = await userRepository.find({
  where: {
    name: 'Alice',
  },
})

Prisma

const user = await prisma.users({
  where: {
    name: 'Alice',
  },
})

Other filter criteria

TypeORM

TypeORM doesn't expose other filter critera. But you can use the QueryBuilder API to send queries using LIKE and other SQL operators.

Prisma

Prisma generates many additional filters that are commonly used in modern application development:

  • <field>_ends_with & <field>_starts_with
  • <field>_not_ends_with & <field>_not_starts_with
  • <field>_gt & <field>_gte
  • <field>_lt & <field>_lte
  • <field>_contains & <field>_not_contains
  • <field>_in & <field>_not_in

Relation filters

TypeORM

TypeORM doesn't offer a dedicated API for relation filters. You can get similar functionality by using the QueryBuilder or writing the queries by hand.

Prisma

Prisma lets you filter a list based on a criteria that applies not only to the models of the list being retrieved, but to a relation of that model.

For example, you want to fetch only those users that wrote a post with the title "Hello World". The filter criteria is therefore not referencing the user model, but the post model that's related to the user model:

query {
  user(where: {
    posts_some: {
      title: "Hello World"
    }
  }) {
    id
  }
}

Pagination

TypeORM

const posts = await getRepository(Post).find({
  skip: 5,
  take: 10,
})

Prisma

const posts = await prisma.posts({
  skip: 5,
  first: 10,
})

In addition to skip and first, the Prisma API also offers:

  • last
  • before & after for cursor based pagination
  • Relay-style pagination

Writing data

Creating objects

TypeORM ()

Using `save`
Using `create`
Using `insert`
const user = new User()
user.name = 'Alice'
user.email = 'alice@prisma.io'
user.save()
Copy

Prisma

const user = new User({
  name: 'Alice',
  email: 'alice@prisma.io',
})

Updating objects

TypeORM

const userRepository = getRepository(User)
const updatedUser = await userRepository.update(id, {
  name: 'James',
  email: 'james@prisma.io',
})

Prisma

const updatedUser = await prisma.updateUser({
  where: { id },
  data: {
    name: 'James',
    email: 'james@prisma.io',
  },
})

Deleting objects

Using `delete`
Using `remove`
const userRepository = getRepository(User)
await userRepository.delete(id)
Copy

Prisma

const deletedUser = await prisma.deleteUser({ id })

Batch updates

TypeORM

TypeORM doesn't offer a dedicated API for batch updates, but you can use save on an array of entities which leads to similar functionality.

Prisma

const updatedUsers = await prisma.updateManyUsers({
  data: {
    role: 'ADMIN',
  },
  where: {
    email_ends_with: '@prisma.io',
  },
})

Batch deletes

Using `delete`
Using `remove`
const userRepository = getRepository(User)
await userRepository.delete([id1, id2, id3])
Copy

Prisma

await prisma.deleteManyUsers({
  id_in: [id1, id2, id3],
})

Transactions

TypeORM

await getConnection().transaction(async transactionalEntityManager => {
  const user = getRepository(User).create({
    name: 'Bob',
    email: 'bob@prisma.io',
  })
  const post1 = getRepository(Post).create({
    title: 'Join us for GraphQL Conf in 2019',
  })
  const post2 = getRepository(Post).create({
    title: 'Subscribe to GraphQL Weekly for GraphQL news',
  })
  user.posts = [post1, post2]
  await transactionalEntityManager.save(post1)
  await transactionalEntityManager.save(post2)
  await transactionalEntityManager.save(user)
})

Prisma

const newUser: User = await prisma.createUser({
  name: 'Bob',
  email: 'bob@prisma.io',
  posts: {
    create: [
      {
        title: 'Join us for GraphQL Conf in 2019',
      },
      {
        title: 'Subscribe to GraphQL Weekly for GraphQL news',
      },
    ],
  },
})