插入时,Knex /异议“重复键值违反唯一约束”

时间:2019-07-05 05:00:24

标签: knex.js objection.js

exports.seed = async function(knex, Promise) {
  await knex.raw('TRUNCATE TABLE posts RESTART IDENTITY CASCADE')
  await knex.raw('TRUNCATE TABLE users RESTART IDENTITY CASCADE')
}

和一些种子数据。...

const faker = require('faker')

const post = [
  {
    id: 1,
    title: faker.lorem.words(),
    body: '12 - 10',
    answers: '[12]',
    user_id: 1
  },
  {
    id: 2,
    title: faker.lorem.words(),
    body: '12 - 10 + 123',
    answers: '[12]',
    user_id: 1
  },
  {
    id: 3,
    title: faker.lorem.words(),
    body: '12 - 10 / 901',
    answers: '[12]',
    user_id: 1
  }
]

exports.seed = (knex, Promise) => {
  // Deletes ALL existing entries
  return knex('post').then(() => {
    // Inserts seed entries
    return knex('post').insert(post)
  })
}

一种简单的更新方法

export async function update(req, res) {
  try {
    const user = await currentUser()
    const params = req.body
    await Post.query()
      .findById(req.params.id)
      .where('user_id', user.id)
      .patch({ ...params, user_id: user.id })

    return res.json({ success: true })
  } catch (err) {
    return res.status(500).json({ message: 'Something went wrong' })
  }
}

当我在测试中插入时,得到一个 duplicate key value violates unique constraint

即使从种子创建的测试数据的ID为[1,2,3],插入内容也会抱怨已使用主数据库。为什么是这样?数据库不应该选择下一个可用的ID吗?

exports.up = async function(knex) {
  await knex.schema.alterTable('posts', (t) => {
    t.integer('user_id')
      .unsigned()
      .references('users.id')
  })
}

exports.down = async function(knex) {
  await knex.schema.table('posts', (t) => {
    t.dropColumn('user_id')
  })
}

编辑

即使仅使用SQL插入。也有错误:

INSERT INTO calcs (title, answers, user_id) VALUES ('tester', '[123]', 1);

结果为: `重复的键值违反了唯一约束posts_pkey'

我不仅仅使用knex del()调用的原因是因为我在删除带有外键引用的表时遇到错误。

2 个答案:

答案 0 :(得分:0)

当您从种子插入数据时,您还将id列值传递给数据库。

这会使您在初始插入种子时,主键id sequence不增加

现在播种后,当您尝试插入更多数据时,id sequence仍返回从1开始的ID。

您应按照播种期间How to reset sequence in postgres and fill id column with new data?的指示,将ID序列设置为在播种过程中正确的值

答案 1 :(得分:0)

您应该修复此部分,而缺少 .del()

exports.seed = (knex, Promise) => {
  // Deletes ALL existing entries
  return knex('post').then(() => {
    // Inserts seed entries
    return knex('post').del().insert(post)
  })
}