web-dev-qa-db-ja.com

Nodejsはバルクアップサートを続編します

続編で一括アップサートを行う方法はありますか。また、重複チェックに使用するキーを指定できますか。

私は次のことを試みましたが、うまくいきませんでした:

Employee.bulkCreate(data, {
    updateOnDuplicate: true
});

ただし、一括作成は正常に機能します。上記のステートメントは、常にDBに新しいエントリを作成します。

19
Ashutosh

公式の sequelizejsリファレンス から。

bulkCreateオプションとupdateOnDuplicateを使用して実行できます。

たとえば次のように:

Employee.bulkCreate(dataArray, 
    {
        fields:["id", "name", "address"] ,
        updateOnDuplicate: ["name"] 
    } )

updateOnDuplicateは、主キー(または一意のキー)が行に一致したときに更新されるフィールドの配列です。モデルとdataArrayの両方に、更新/挿入用の一意のフィールド(idとしましょう)が少なくとも1つあることを確認してください。

32
followtest52

PostgreSQLは回答でサポートされていないため、Sequelizeを使用した "" "" best "" ""の代替手段は ON CONFLICT ステートメント。例(TypeScript):

const values: Array<Array<number | string>> = [
    [1, 'Apple', 'Red', 'Yummy'],
    [2, 'Kiwi', 'Green', 'Yuck'],
]

const query = 'INSERT INTO fruits (id, name, color, flavor) VALUES ' +
     values.map(_ => { return '(?)' }).join(',') +
     ' ON CONFLICT (id) DO UPDATE SET flavor = excluded.flavor;'

sequelize.query({ query, values }, { type: sequelize.QueryTypes.INSERT })

これにより、次のようなクエリが作成されます。

INSERT INTO 
    fruits (id, name, color, flavor)
VALUES 
    (1, 'Apple', 'Red', 'Yummy'),
    (2, 'Kiwi', 'Green', 'Yuck')
ON CONFLICT (id) DO UPDATE SET 
    flavor = excluded.flavor;

これは、sequelizeを使用する目的に反するため、手動でクエリを作成するのに理想的なソリューションではありませんが、必然的に必要のない1回限りのクエリの場合は、この方法を使用できます。

8
Can

コメントできないので、答えを追加します。 Mysql、Mariadbの場合、次を使用できます。

Model.bulkCreate(dataArray, {updateOnDuplicate: []});

上記を使用すると、新規の場合は挿入され、重複している場合はすべてのフィールドが更新されます。すべてを更新する場合は、フィールドを宣言する必要はありません。

0
blankstar85