javascript 未处理的拒绝序列化数据库错误:关系"用户"不存在

e0uiprwp  于 2023-02-15  发布在  Java
关注(0)|答案(8)|浏览(141)

我正在开始使用Sequelize。我正在遵循他们网站上提供的文档: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'
    });
  });

到目前为止,一切都运行得很完美。而且表"user"被正确地构建和填充。(虽然我不明白Sequelize会自动在"user"后面附加一个"s",但任何解释都可以。)

但是,当我添加以下代码部分时:

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

我得到这个错误:
未处理的拒绝序列化数据库错误:关系"用户"不存在
所以我的问题是:
1.为什么Sequelize要在user后面加一个"s"(我知道这很有道理,但是开发者不应该决定吗?)
1.是什么导致了这个错误?我按照文档操作,但它仍然不起作用?

ldioqlga

ldioqlga1#

当您定义模型时,您可以添加配置,在这种情况下,您必须添加的选项是freezeTableName,以防止名称为复数。

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,
  });
ui7jx7zq

ui7jx7zq2#

还有一种有趣的方法可以避免这种情况,但你需要真正关注这种实现方式。

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

您有意将user放在这里,并在其他编码位置使用users(假设sequelize会自动将所有传递的模型名称(define的第一个参数)转换为复数)。

cvxl0en2

cvxl0en23#

出现这个问题是因为创建表是一个异步函数。问题是,findAll()函数可以在表还没有创建的时候执行。要解决这个问题,可以用途:

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

})();
ycggw6v2

ycggw6v24#

在我的例子中,问题是没有创建表users,您可以使用CREATE TABLE IF NOT EXISTS(SQL)手动创建该表,或者在选项对象中添加tableName = "users"

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"
    }
);
j9per5c4

j9per5c45#

运行代码两次。
在第二次运行之前,注解掉以下代码,

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

dddzy1tm6#

也许答案与您的问题不完全相关,但我想描述一下我的经验与此错误
错误:关系“users”不存在。
看起来Sequelize是根据迁移文件名和它的字母顺序进行迁移的。我的问题是我的文件命名没有排序,以便创建正确的连接。如果你面临这个问题,请确保你的迁移文件是按正确的顺序(按字母顺序)发射的。
正确的顺序是首先迁移没有连接的表(例如table_A),然后迁移与table_A有连接的表。
正如我所说,这可能不是你的特定订单的答案,但我想分享我的经验,因为我没有找到这个信息在互联网上时,我正在寻找这个错误。

sg3maiej

sg3maiej7#

只需将tableName: "Users"附加到模型配置中。
我发现最简单的解决方法是显式地在模型上设置tableName。正如其他人所提到的,sequelize默认使用模型的复数形式作为表名。例如,User将变为Users。
查询时,sequelize将查找与模型User同名的表。通过在模型中定义tableName,sequelize应搜索正确的表。将tableName: "Users"附加到模型配置,即:

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

tjjdgumg8#

如果您希望Sequelize对模型使用单数单词('info '),对表使用相同的单数单词('info'),您可以将模型命名为'info',并将tablename: 'info'添加到模型的定义中。
这是一种控制Sequelize的默认行为的方法,即逐个表地将模型名称复数化或不复数化。

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

相关问题