我们如何在后缀orm中实现像bulkUpdate这样的bulkCreate,我搜索了整个封存文档,但是没有找到任何与bulkUpdate相关的文档,所以我尝试在for循环中循环更新,它可以工作,但是还有其他方法来批量更新吗?
发布于 2019-02-27 08:00:14
使用bulkCreate to bulkUpdate方法。
bulkCreate([...], { updateOnDuplicate: ["name"] })updateOnDuplicate是一个字段数组,当主键(或可能是唯一键)匹配行时,这些字段将被更新。确保您的模型和dataArray中至少有一个唯一字段(假设id),这两个字段都用于向上插入。
供参考请参阅这里
发布于 2020-09-03 16:03:50
你可以,如果你想用相同的值更新很多记录!示例:我希望每次为10个用户更新字段"activationStatus“,在DB中更新1个用户=1条记录,然后我有用户in数组:
User.update({ activationStatus: 'active'}, {
where: {
id: [1,2,3,4,5,6,7,8,9,10]
}
});它将类似于SQL查询:
UPDATE User SET activationStatus = 'active' WHERE id IN(1,2,3,4,5,6,7,8,9,10);您可以找到更多有关后缀操作符别名这里的信息。
发布于 2021-09-03 11:23:41
最小bulkCreate updateOnDuplicate + updateOnDuplicate示例
只是为了澄清在https://stackoverflow.com/a/54900639/895245上提到了什么
const assert = require('assert');
const path = require('path');
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize({
dialect: 'sqlite',
storage: 'tmp.' + path.basename(__filename) + '.sqlite',
});
(async () => {
const Integer = sequelize.define('Integer',
{
value: {
type: DataTypes.INTEGER,
unique: true, // mandatory
primaryKey: true,
},
name: {
type: DataTypes.STRING,
},
inverse: {
type: DataTypes.INTEGER,
},
},
{
timestamps: false,
}
);
await Integer.sync({force: true})
await Integer.create({value: 2, inverse: -2, name: 'two'});
await Integer.create({value: 3, inverse: -3, name: 'three'});
await Integer.create({value: 5, inverse: -5, name: 'five'});
// Initial state.
assert.strictEqual((await Integer.findOne({ where: { value: 2 } })).name, 'two');
assert.strictEqual((await Integer.findOne({ where: { value: 3 } })).name, 'three');
assert.strictEqual((await Integer.findOne({ where: { value: 5 } })).name, 'five');
assert.strictEqual((await Integer.findOne({ where: { value: 2 } })).inverse, -2);
assert.strictEqual((await Integer.findOne({ where: { value: 3 } })).inverse, -3);
assert.strictEqual((await Integer.findOne({ where: { value: 5 } })).inverse, -5);
assert.strictEqual(await Integer.count(), 3);
// Update.
await Integer.bulkCreate(
[
{value: 2, name: 'TWO'},
{value: 3, name: 'THREE'},
{value: 7, name: 'SEVEN'},
],
{ updateOnDuplicate: ["name"] }
);
// Final state.
assert.strictEqual((await Integer.findOne({ where: { value: 2 } })).name, 'TWO');
assert.strictEqual((await Integer.findOne({ where: { value: 3 } })).name, 'THREE');
assert.strictEqual((await Integer.findOne({ where: { value: 5 } })).name, 'five');
assert.strictEqual((await Integer.findOne({ where: { value: 7 } })).name, 'SEVEN');
assert.strictEqual((await Integer.findOne({ where: { value: 2 } })).inverse, -2);
assert.strictEqual((await Integer.findOne({ where: { value: 3 } })).inverse, -3);
assert.strictEqual((await Integer.findOne({ where: { value: 5 } })).inverse, -5);
assert.strictEqual(await Integer.count(), 4);
await sequelize.close();
})();生成的SQLite更新查询:
INSERT INTO `IntegerNames` (`value`,`name`) VALUES (2,'TWO'),(3,'THREE'),(7,'SEVEN')
ON CONFLICT (`value`) DO UPDATE SET `name`=EXCLUDED.`name`;update 最小示例
为了补充在https://stackoverflow.com/a/63727529/895245中提到的内容,您不需要使用固定值进行更新,还可以使用其他列和SQL函数,例如:
const assert = require('assert');
const path = require('path');
const { Sequelize, DataTypes, Op } = require('sequelize');
const sequelize = new Sequelize({
dialect: 'sqlite',
storage: 'tmp.' + path.basename(__filename) + '.sqlite',
});
(async () => {
const Inverses = sequelize.define('Inverses',
{
value: {
type: DataTypes.INTEGER,
primaryKey: true,
},
inverse: {
type: DataTypes.INTEGER,
},
name: {
type: DataTypes.STRING,
},
},
{ timestamps: false }
);
await Inverses.sync({force: true})
await Inverses.create({value: 2, inverse: -2, name: 'two'});
await Inverses.create({value: 3, inverse: -3, name: 'three'});
await Inverses.create({value: 5, inverse: -5, name: 'five'});
// Initial state.
assert.strictEqual((await Inverses.findOne({ where: { value: 2 } })).inverse, -2);
assert.strictEqual((await Inverses.findOne({ where: { value: 3 } })).inverse, -3);
assert.strictEqual((await Inverses.findOne({ where: { value: 5 } })).inverse, -5);
assert.strictEqual(await Inverses.count(), 3);
// Update to fixed value.
await Inverses.update(
{ inverse: 0, },
{ where: { value: { [Op.gt]: 2 } } },
);
assert.strictEqual((await Inverses.findOne({ where: { value: 2 } })).inverse, -2);
assert.strictEqual((await Inverses.findOne({ where: { value: 3 } })).inverse, 0);
assert.strictEqual((await Inverses.findOne({ where: { value: 5 } })).inverse, 0);
assert.strictEqual(await Inverses.count(), 3);
// Update to match another column.
await Inverses.update(
{ inverse: sequelize.col('value'), },
{ where: { value: { [Op.gt]: 2 } } },
);
assert.strictEqual((await Inverses.findOne({ where: { value: 2 } })).inverse, -2);
assert.strictEqual((await Inverses.findOne({ where: { value: 3 } })).inverse, 3);
assert.strictEqual((await Inverses.findOne({ where: { value: 5 } })).inverse, 5);
assert.strictEqual(await Inverses.count(), 3);
// Update to match another column with modification.
await Inverses.update(
{ inverse: sequelize.fn('1 + ', sequelize.col('value')), },
{ where: { value: { [Op.gt]: 2 } } },
);
assert.strictEqual((await Inverses.findOne({ where: { value: 2 } })).inverse, -2);
assert.strictEqual((await Inverses.findOne({ where: { value: 3 } })).inverse, 4);
assert.strictEqual((await Inverses.findOne({ where: { value: 5 } })).inverse, 6);
assert.strictEqual(await Inverses.count(), 3);
// A string function test.
await Inverses.update(
{ name: sequelize.fn('upper', sequelize.col('name')), },
{ where: { value: { [Op.gt]: 2 } } },
);
assert.strictEqual((await Inverses.findOne({ where: { value: 2 } })).name, 'two');
assert.strictEqual((await Inverses.findOne({ where: { value: 3 } })).name, 'THREE');
assert.strictEqual((await Inverses.findOne({ where: { value: 5 } })).name, 'FIVE');
assert.strictEqual(await Inverses.count(), 3);
await sequelize.close();
})();生成的SQLite更新查询:
UPDATE `Inverses` SET `inverse`=$1 WHERE `value` > 2
UPDATE `Inverses` SET `inverse`=`value` WHERE `value` > 2
UPDATE `Inverses` SET `inverse`=1 + (`value`)
UPDATE `Inverses` SET `name`=upper(`name`) WHERE `value` > 2QueryInterface.bulkUpdate 迁移的最小示例
让我困惑的是有QueryInterface,但没有一个Model。
部分原因似乎是没有办法在迁移中进行非原始查询,如:https://github.com/sequelize/cli/issues/862和非原始查询一样,我们可以使用上面所示的.update。这个bulkUpdate似乎是一个更原始的版本,可以用于迁移。
在本例中,我向数据库添加了一个新的https://github.com/cirosantilli/cirodown/blob/bulk-update-col/web/migrations/20210903000000-user-add-display-name-column.js列,并希望它基于现有的username列。
下面是一个如何使displayName与username相同的示例。注意,它实际上并没有使用像Model.bulkCreate这样的数组输入,它只是运行一个SQL UPDATE查询,所以命名有点混乱:
module.exports = {
up: async (queryInterface, Sequelize) => queryInterface.sequelize.transaction(async transaction => {
await queryInterface.addColumn('User', 'displayName',
{
type: Sequelize.STRING(256),
allowNull: false,
defaultValue: '',
},
{transaction},
)
await queryInterface.bulkUpdate('User',
{displayName: queryInterface.sequelize.col('username')},
{}, // optional where clause to select which rows to update
// If empty like this it updates every single row.
{transaction},
)
}),
down: async (queryInterface, Sequelize) => {
await queryInterface.removeColumn('User', 'displayName')
}
};创建的相关示例:在后缀迁移脚本中添加数据?
迁移QueryInterface.bulkInsert的TODO + 最小示例
好的,现在我想在迁移过程中实际插入一个数组,因为我的修改太复杂了,不能在SQL中使用bulkUpdate完成:我必须将数据导入Node,然后将其推回去。
我希望下面的方法能起作用,但没有,而且由于完全没有回溯痕迹.我不知道为什么:
module.exports = {
up: async (queryInterface, Sequelize) => queryInterface.sequelize.transaction(async transaction => {
await queryInterface.addColumn('User', 'displayName',
{
type: Sequelize.STRING(256),
allowNull: false,
defaultValue: '',
},
{transaction},
)
const [users] = await queryInterface.sequelize.query('SELECT * FROM "User";', { transaction });
const newUsers = users.map(user =>
{ return { id: user.id, displayName: user.username } }
)
await queryInterface.bulkInsert('User',
newUsers,
{
updateOnDuplicate: ['displayName'],
transaction,
}
)
}),
down: async (queryInterface, Sequelize) => {
await queryInterface.removeColumn('User', 'displayName')
}
};在以下方面失败:
ERROR: Cannot read property 'map' of undefined测试的后缀6.5.1,sqlite3 5.0.2,节点v14.17.0,Ubuntu21.04。
https://stackoverflow.com/questions/54898994
复制相似问题