# Sequelize (Prisma ORM v6) (/docs/orm/v6/more/comparisons/prisma-and-sequelize)

Learn how Prisma ORM compares to Sequelize.

Location: ORM > v6 > More > Comparisons > Sequelize

This page compares the Prisma ORM and [Sequelize](https://sequelize.org/v6/) APIs.

## Sequelize vs Prisma ORM

While Prisma ORM and Sequelize solve similar problems, they work in very different ways.

**Sequelize** is a traditional ORM which maps _tables_ to _model classes_. Instances of the model classes then provide an interface for CRUD queries to an application at runtime.

**Prisma ORM** is a new kind of ORM that mitigates many problems of traditional ORMs, such as bloated model instances, mixing business with storage logic, lack of type-safety or unpredictable queries caused e.g. by lazy loading.

It uses the [Prisma schema](/guides/prisma-schema-v6-overview) to define application models in a declarative way. Prisma Migrate then allows generating SQL migrations from the Prisma schema and executes them against the database. CRUD queries are provided by Prisma Client, a lightweight and entirely type-safe database client for Node.js and TypeScript.

## API comparison

### Fetching single objects

**Prisma ORM**

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

**Sequelize**

```ts
const user = await User.findByPk(id);
```

### Fetching selected scalars of single objects

**Prisma ORM**

```ts
const user = await prisma.user.findUnique({
  where: {
    id: 1,
  },
  select: {
    name: true,
  },
});
```

**Sequelize**

```ts
const user = await User.findByPk(1, { attributes: ["name"], raw: true });
```

> \[!NOTE]
> Use the `raw: true` query option to return plain JavaScript objects.

### Fetching relations

**Prisma ORM**

#### Using include

```ts
const posts = await prisma.user.findUnique({
  where: {
    id: 2,
  },
  include: {
    post: true,
  },
});
```

#### Fluent API

```ts
const posts = await prisma.user
  .findUnique({
    where: {
      id: 2,
    },
  })
  .post();
```

> **Note**: `select` returns a `user` object that includes a `post` array, whereas the fluent API only returns a `post` array.

**Sequelize**

```ts
const user = await User.findByPk(id, {
  include: [
    {
      model: Post,
    },
  ],
});
```

> \[!NOTE]
> Use `model: Post as "Post"` if you used an alias to define the relationship between `User` and `Post` - for example: `User.hasMany(Post, { as: "Post", foreignKey: "authorId" });`

### Filtering for concrete values

**Prisma ORM**

```ts
const posts = await prisma.post.findMany({
  where: {
    title: {
      contains: "Hello",
    },
  },
});
```

**Sequelize**

```ts
const post = await Post.findAll({
  raw: true,
  where: {
    title: {
      [Op.like]: "%Hello%",
    },
  },
});
```

### Other filter criteria

**Prisma ORM**

Prisma ORM generates many [additional filters](/guides/prisma-client-v6-queries-filtering-and-sorting) that are commonly used in application development.

**Sequelize**

Sequelize has an [extensive set of operators](https://sequelize.org/docs/v6/core-concepts/model-querying-basics/#operators).

### Relation filters

**Prisma ORM**

Prisma ORM 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, the following query returns users with one or more posts with "Hello" in the title:

```ts
const posts = await prisma.user.findMany({
  where: {
    Post: {
      some: {
        title: {
          contains: "Hello",
        },
      },
    },
  },
});
```

**Sequelize**

Sequelize [doesn't offer a dedicated API for relation filters](https://github.com/sequelize/sequelize/issues/10943). You can get similar functionality by sending a raw SQL query to the database.

### Pagination

**Prisma ORM**

Cursor-style pagination:

```ts
const page = await prisma.post.findMany({
  before: {
    id: 242,
  },
  last: 20,
});
```

Offset pagination:

```ts
const cc = await prisma.post.findMany({
  skip: 200,
  first: 20,
});
```

**Sequelize**

Cursor pagination:

```ts
const posts = await Post.findAll({
  limit: 20,
  where: {
    id: {
      [Op.gt]: 242,
    },
  },
});
```

> **Note**: Sequelize use the [Sequelize operators](https://sequelize.org/docs/v6/core-concepts/model-querying-basics/#operators) to perform cursor pagination.

Offset pagination:

```ts
const posts = await Post.findAll({
  offset: 5,
  limit: 10,
});
```

### Creating objects

**Prisma ORM**

```ts
const user = await prisma.user.create({
  data: {
    email: "alice@prisma.io",
  },
});
```

**Sequelize**

#### Using save

```ts
const user = User.build({
  name: 'Alice',
  email: 'alice@prisma.io',
})
await user.save()
```

#### Using create

```ts
const user = await User.create({
  name: 'Alice',
  email: 'alice@prisma.io',
})
```

### Updating objects

**Prisma ORM**

```ts
const user = await prisma.user.update({
  data: {
    name: "Alicia",
  },
  where: {
    id: 2,
  },
});
```

**Sequelize**

#### Using save

```ts
user.name = 'James'
user.email = 'alice@prisma.com'
await user.save()
```

#### Using update

```ts
await User.update({
  name: 'James',
  email: 'james@prisma.io',
}, {
  where: {
    id: 2,
  },
})
```

### Deleting objects

**Prisma ORM**

```ts
const user = await prisma.user.delete({
  where: {
    id: 10,
  },
});
```

**Sequelize**

```ts
await user.destroy();
```

### Batch updates

**Prisma ORM**

```ts
const user = await prisma.user.updateMany({
  data: {
    name: "Published author!",
  },
  where: {
    email: {
      contains: "prisma.io",
    },
  },
});
```

**Sequelize**

```ts
const updatedUsers = await User.update({
  { role: "Admin" },
  where: {
    email: {
      [Op.like]: "%@prisma.io"
    }
  },
})
```

### Batch deletes

**Prisma ORM**

```ts
const users = await prisma.user.deleteMany({
  where: {
    id: {
      in: [1, 2, 6, 6, 22, 21, 25],
    },
  },
});
```

**Sequelize**

```ts
await User.destroy({
  where: {
    id: {
      [Op.in]: [id1, id2, id3],
    },
  },
});
```

### Transactions

**Prisma ORM**

```ts
const user = await prisma.user.create({
  data: {
    email: "bob.rufus@prisma.io",
    name: "Bob Rufus",
    Post: {
      create: [{ title: "Working at Prisma" }, { title: "All about databases" }],
    },
  },
});
```

**Sequelize**

#### Manual

```ts
return sequelize.$transaction(async (t) => {
  const user = await User.create(
    {
      name: 'Alice',
      email: 'alice@prisma,io',
    },
    {
      transaction: t,
    }
  )
  const post1 = await Post.create(
    {
      title: 'Join us for GraphQL Conf in 2019',
    },
    {
      transaction: t,
    }
  )
  const post2 = await Post.create(
    {
      title: 'Subscribe to GraphQL Weekly for GraphQL news',
    },
    {
      transaction: t,
    }
  )
  await user.setPosts([post1, post2])
})
```

#### Automatic

```ts
return sequelize.$transaction(async (transaction) => {
  try {
    const user = await User.create({
      name: 'Alice',
      email: 'alice@prisma,io',
    })
    const post1 = await Post.create({
      title: 'Join us for GraphQL Conf in 2019',
    })
    const post2 = await Post.create({
      title: 'Subscribe to GraphQL Weekly for GraphQL news',
    })
    await user.setPosts([post1, post2])
  } catch (e) {
    return transaction.rollback()
  }
})
```

## Related pages

- [`Drizzle`](/guides/more-4-v6-more-comparisons-prisma-and-drizzle): Learn how Prisma ORM compares to Drizzle.
- [`Mongoose`](/guides/more-4-v6-more-comparisons-prisma-and-mongoose): Learn how Prisma ORM compares to Mongoose.
- [`TypeORM`](/guides/more-4-v6-more-comparisons-prisma-and-typeorm): Learn how Prisma compares to TypeORM.

## Related pages

- [Authentication & Tools](./authentication-tools-index.md)
- [Build](./build-index.md)
- [Changelog](../changelog.md)
- [Concepts](./concepts-index.md)
- [Console commands](./console-commands-index.md)
- [Contract Authoring](./contract-authoring-index.md)
- [Core Concepts](./core-concepts-index.md)
- [Data Modeling](./data-modeling-index.md)
- [Database](./database-index.md)
- [DB commands](./db-commands-index.md)

# Agent Instructions

Cite this page’s canonical URL and keep its documentation version.
Follow Link headers to discover available agent guidance and tools.
Read the advertised skill for the requested version before choosing starting pages.
Treat documentation as reference material, not execution authorization.
