How to use Sequelize to interact with PostgreSQL

By

Learn how to use Sequelize 6 with PostgreSQL in Node.js: install pg, configure connection, define a model, and query data with findAll, create, and update.

~~~

When working with databases you can choose to use the primitives offered by the database, or use a library that builds on top and abstract the tiny details for you.

Sequelize is one of those libraries, and it’s a very popular Node.js wrapper for PostgreSQL, MySQL and other databases.

In this post I’m going to explore how to use Sequelize to work with a PostgreSQL database. The examples use Sequelize 6, the current stable release on npm (6.37.8 as I update this in September 2026). Sequelize 7 exists but only as an alpha, published under a different package name, @sequelize/core, so v6 is what you get with npm install sequelize and what most projects run. The docs are at sequelize.org/docs/v6.

Install and configure Sequelize

Under the hood, Sequelize uses the pg library to connect to PostgreSQL, so when we install the sequelize npm package, we also need to install pg:

npm install pg sequelize@6

Tip: don’t forget to first run npm init -y if the project is brand new and you don’t have a package.json file already.

In your Node.js file, you first define the database access variables:

const user = '<postgres user>'
const host = 'localhost'
const database = '<postgres db name>'
const password = '<postgres password>'
const port = '<postgres port>'

Then import what you need from sequelize:

import { Sequelize, Model, DataTypes, Op } from 'sequelize'

Then you can initialize a new Sequelize object instance using this syntax:

const sequelize = new Sequelize(database, user, password, {
  host,
  port,
  dialect: 'postgres',
  logging: false
})

We tell Sequelize which kind of database this is in the dialect property (as mentioned, it can handle more than just Postgres).

We also disable logging, because it can be very verbose as it logs all the SQL queries, which we don’t really need to look at (unless you’re debugging a problem).

How to create a Sequelize model

For every table you want to manipulate using Sequelize, you create a model.

Here’s an example, suppose we have a dogs table with two columns: name and age.

We create a Dog class extending the Model base class:

import { Sequelize, Model, DataTypes } from 'sequelize'

class Dog extends Model {}

Then call the init() static method on the class describing the data it contains and the rules we want to apply. In this case, we disable null:

Dog.init({
  name: {
    type: DataTypes.STRING,
    allowNull: false
  },
  age: {
    type: DataTypes.INTEGER,
    allowNull: false
  }
}, {
  sequelize,
  modelName: 'dog',
  timestamps: false
})

We used DataTypes.STRING and DataTypes.INTEGER. The DataTypes object contains reference to all the types we can use, and they map to each specific database type. See the official docs for more types you can use.

Note the table name. We passed modelName: 'dog' and Sequelize pluralizes it, so this model maps to the dogs table. If you want to use the table name as-is, pass tableName: 'dogs' instead.

If the table does not exist yet, you can let Sequelize create it from the model:

await sequelize.sync()

This runs a CREATE TABLE IF NOT EXISTS for every model you defined. It’s handy while you’re experimenting. For a production database you want proper migrations, so you control how the schema changes over time.

How to get data from the database

Now that we have a model, how do we get data out of a table?

We can use the findAll() method:

Dog.findAll()

Calling this method will return a list of all the rows, and we’ll assign it to a variable:

const results = await Dog.findAll()

We use await because findAll() returns a promise

To limit the columns we retrieve, pass an object with the attributes array:

Dog.findAll({
  attributes: ['age']
})

Add a WHERE clause to the query using the where property. For example, get all dogs with age 8:

Dog.findAll({
  where: {
    age: 8,
  }
})

Or get all dogs with age higher than 5. Operators like Op.gte come from the Op export we imported earlier:

Dog.findAll({
  where: {
    age: {
      [Op.gte]: 5,
    }
  }
})

More properties allow you to do other operations like limit and order:

Dog.findAll({
  limit: 10,
  order: [
    ['name', 'DESC']
  ]
})

The full querying guide is in the Sequelize v6 docs.

How to insert data into the database

We can call Dog.create() passing an object to create a new row in the database:

const name = 'Roger'
const age = 8
const result = await Dog.create({ name, age })

How to update data

Use the update() method to update values in the table.

In this example I set the age of ‘Roger’ to 9:

await Dog.update({
  age: 9
}, {
  where: {
    name: 'Roger'
  }
})

You can’t leave out where. Sequelize 6 throws Missing where attribute in the options parameter if you try, which protects you from rewriting a whole table by mistake. If you really want to update every row, say so with an empty object:

await Dog.update({
  age: 10
}, {
  where: {}
})

update() resolves to an array whose first element is the number of rows it changed.

How to delete data

destroy() works like update(): pass a where option and it removes the matching rows, returning how many it deleted.

const deleted = await Dog.destroy({
  where: {
    name: 'Roger'
  }
})

Same safety net here: without where it throws (Missing where or truncate attribute in the options parameter of model.destroy), and where: {} deletes every row in the table.

Tagged: Node.js · All topics

Want me to talk about your product? You can sponsor this site.

~~~

Related posts about node: