AG_HIHI
AG_HIHI

Reputation: 2005

Unhandled rejection SequelizeDatabaseError: relation "users" does not exist

I am getting started with Sequelize. I am following the documentation they are providing on their website :http://docs.sequelizejs.com/manual/installation/getting-started.html

const Sequelize = require('sequelize');
const sequelize = new Sequelize('haha', 'postgres', 'postgres', {
  host: 'localhost',
  dialect: 'postgres',
  operatorsAliases: false,

  pool: {
    max: 5,
    min: 0,
    acquire: 30000,
    idle: 10000
  },

  // SQLite only
  storage: 'path/to/database.sqlite'
});


sequelize
  .authenticate()
  .then(() => {
    console.log('Connection has been established successfully.');
  })
  .catch(err => {
    console.error('Unable to connect to the database:', err);
  });


  const User = sequelize.define('user', {
    firstName: {
      type: Sequelize.STRING
    },
    lastName: {
      type: Sequelize.STRING
    }
  });

  // force: true will drop the table if it already exists
  User.sync({force: true}).then(() => {
    // Table created
    return User.create({
      firstName: 'John',
      lastName: 'Hancock'
    });
  });

Up until here, everything works perfectly. And the table "user" is correctly built and populated. (Although I do not understand Sequelize appends an "s" automatically to "user", any explanation.)

enter image description here

enter image description here

However when I add the following portion of code:

User.findAll().then(users => {
  console.log(users)
})

I get this error :

Unhandled rejection SequelizeDatabaseError: relation "users" does not exist

So my questions are:

  1. Why does Sequelize add an "s" to user. (I know it makes sense but shouldn't the developer decide that)
  2. What is causing that error? I followed the documentation but it still didn't work?

Upvotes: 13

Views: 52218

Answers (8)

daffa fathani adila
daffa fathani adila

Reputation: 51

This problem occurs because creating a table is an asynchronous function. The problem is, the findAll() function can get executed while the table has not been created. to solve this, you can use:


(async ()=>{
    await User.sync({force: true});
    // Table created
    const users=await User.findAll();
    console.log(users);

})();



Upvotes: 5

David
David

Reputation: 1141

If you want Sequelize to use a singular word ('info') for a model and that same singular word for the table ('info'), you can name the model 'info' and also add tablename: 'info' to the definition of your model.

This is a way to control Sequelize's default behavior of pluralizing model names, or not, on a table-by-table basis.

info.js
module.exports = (sequelize, DataTypes) => {
  const info = sequelize.define('info', {
    firstname: DataTypes.STRING,
    email: DataTypes.STRING,
    phone: DataTypes.STRING,
  }, {
      tableName: 'info'
  });
  return info;
};

Upvotes: 1

tufac2
tufac2

Reputation: 778

The problem, in my case, was that the table users was not created. You can create the table manually with CREATE TABLE IF NOT EXISTS (SQL) or add the tableName = "users" in the options object:

export const User = db.define('user',
    {
        id: {
            type: DataTypes.UUIDV4,
            autoIncrement: true,
            primaryKey: true,
        },
        name: {
            type: new DataTypes.STRING(128),
            allowNull: false,
        },
        email: {
            type: new DataTypes.STRING(128),
            allowNull: true,
        },
        password: {
            type: new DataTypes.STRING(128),
            allowNull: true,
        },
    },
    {
        freezeTableName: true,
        tableName: "users"
    }
);

Upvotes: 3

JohnDoe
JohnDoe

Reputation: 545

Simply append tableName: "Users" to your model configuration.

The easiest way I found to solve, is to explicitly set the tableName on the model. As others have mentioned, sequelize defaults to the plural form of a model as the table name. For instance User, becomes Users.

When you query, sequelize looks after a table with the same name as your model User. By defining the tableName in the model, sequelize should search the correct table. Append tableName: "Users" to your model configuration i.e:

 User.init(
        {
            email: DataTypes.STRING,
            password: DataTypes.STRING,
            role: DataTypes.INTEGER,
        },
        {
            sequelize,
            modelName: 'User',
            tableName: 'Users',
        }
    );

Upvotes: 1

Andrew
Andrew

Reputation: 88

Maybe answer is not entirely connected with you question but I want to describe my experience with this error

Error: relation "users" does not exist.

It appears Sequelize make migrations based on migrations file names and it alphabetical order. My problem was my files naming was not sorted in order to create proper connections. If you face with this problem make sure yours migration files are fired in proper (in alphabetically) order.

The proper order is to first migrate table without connections (eg. table_A) and then tables with connections to table_A.

As I said this may not be answer for your particular order but I want to share my experiences because I didn't find this information on the internet when I was looking for this error.

Upvotes: 1

Sahan Dissanayaka
Sahan Dissanayaka

Reputation: 621

There is another interesting way you can avoid this. But you need to really focus on this way of implementation.

const User = sequelize.define("user", {
    firstname: {
      type: Sequelize.STRING
    },
    lastname: {
      type: Sequelize.STRING
    }
  });

you intentionally put user here and use users in other places of coding(Assume sequelize will automatically transform all passed model names (first parameter of define) into plural) . This way of coding will simplify your code.

Upvotes: 6

ccordon
ccordon

Reputation: 1102

When you are defining your model you can add configurations, in this case the option that you must add is freezeTableName prevents the names from being plural.

const User = sequelize.define('user', {
  firstName: {
    type: Sequelize.STRING
  },
  lastName: {
    type: Sequelize.STRING
  }
}, {
    // disable the modification of table names; By default, sequelize will automatically
    // transform all passed model names (first parameter of define) into plural.
    // if you don't want that, set the following
    freezeTableName: true,
  });

Upvotes: 21

JamesSchiiller
JamesSchiiller

Reputation: 83

Run that code twice.

Before running the second time, comment out the following code,

// force: true will drop the table if it already exists
User.sync({force: true}).then(() => {
  // Table created
  return User.create({
    firstName: 'John',
    lastName: 'Hancock'
  });
});

Upvotes: 1

Related Questions