In this tutorial, we'll create a Node.js application using Sequelize as the ORM, PostgreSQL as the database, and demonstrate how to define and use a hasOne association between two models: User and Address.
Prerequisites
Before we start, ensure you have the following installed:
- Node.js and npm.
- PostgreSQL installed and running.
Step 1: Setting Up the Project
Initialize a new Node.js project:
mkdir sequelize-postgres-example cd sequelize-postgres-example npm init -y
Install the required dependencies:
npm install express sequelize pg pg-hstore npm install --save-dev sequelize-cli
Step 2: Initialize Sequelize
Initialize Sequelize in your project:
npx sequelize-cli init
This command generates the following directory structure:
project/ ├── config/ │ └── config.json ├── migrations/ ├── models/ │ └── index.js ├── seeders/ └── package.json
Configure the database connection in config/config.json:
{
"development": {
"username": "your_username",
"password": "your_password",
"database": "sequelize_example",
"host": "127.0.0.1",
"dialect": "postgres"
}
}
Create the database:
createdb sequelize_example
Step 3: Create Models
We'll create two models: User and Address. The User model will have a hasOne association with the Address model.
Generate the Models
Run the following commands:
npx sequelize-cli model:generate --name User --attributes name:string,email:string npx sequelize-cli model:generate --name Address --attributes street:string,city:string,userId:integer
Step 4: Define the hasOne Association
Edit the generated models in the models folder.
models/user.js
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class User extends Model {
static associate(models) {
// Define a hasOne association with Address
User.hasOne(models.Address, { foreignKey: 'userId', as: 'address' });
}
}
User.init(
{
name: DataTypes.STRING,
email: DataTypes.STRING,
},
{ sequelize, modelName: 'User' }
);
return User;
};
models/address.js
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Address extends Model {
static associate(models) {
// Define a belongsTo association with User
Address.belongsTo(models.User, { foreignKey: 'userId', as: 'user' });
}
}
Address.init(
{
street: DataTypes.STRING,
city: DataTypes.STRING,
userId: DataTypes.INTEGER,
},
{ sequelize, modelName: 'Address' }
);
return Address;
};
Step 5: Sync Database
Run migrations to create the tables in your PostgreSQL database:
npx sequelize-cli db:migrate
Step 6: Seed Some Data
We’ll create seeders to populate the database with sample data.
Generate Seeders
npx sequelize-cli seed:generate --name demo-user
Edit the Seeder (seeders/{timestamp}-demo-user.js)
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
const userId = await queryInterface.bulkInsert(
'Users',
[
{
name: 'John Doe',
email: 'john.doe@example.com',
createdAt: new Date(),
updatedAt: new Date(),
},
],
{ returning: true }
);
await queryInterface.bulkInsert('Addresses', [
{
street: '123 Main St',
city: 'Sample City',
userId: userId[0].id,
createdAt: new Date(),
updatedAt: new Date(),
},
]);
},
async down(queryInterface, Sequelize) {
await queryInterface.bulkDelete('Addresses', null, {});
await queryInterface.bulkDelete('Users', null, {});
},
};
Run the seeders:
npx sequelize-cli db:seed:all
Step 7: Query Data
Let’s write a small Express application to fetch users along with their addresses.
Create app.js
const express = require('express');
const db = require('./models');
const app = express();
app.use(express.json());
app.get('/users', async (req, res) => {
try {
const users = await db.User.findAll({
include: [{ model: db.Address, as: 'address' }],
});
res.json(users);
} catch (error) {
console.error(error);
res.status(500).send('Server Error');
}
});
app.listen(3000, async () => {
await db.sequelize.authenticate();
console.log('Server is running on http://localhost:3000');
});
Step 8: Test the Application
Start the server:
node app.js
Access the endpoint:
- Open your browser or use Postman to visit:
http://localhost:3000/users
Response:
[
{
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com",
"createdAt": "2024-11-23T12:34:56.789Z",
"updatedAt": "2024-11-23T12:34:56.789Z",
"address": {
"id": 1,
"street": "123 Main St",
"city": "Sample City",
"userId": 1,
"createdAt": "2024-11-23T12:34:56.789Z",
"updatedAt": "2024-11-23T12:34:56.789Z"
}
}
]
Conclusion
You’ve successfully built a Node.js application with Sequelize and PostgreSQL, defined a hasOne association, and queried related data. This approach is scalable and can be extended to handle more complex relationships in your application.













