在迁移中是否可以使用sequelize更新Postgresql数据库中的现有数据

我正在尝试使用序列迁移向模型添加字段,并且需要从“向上”迁移中更新数据。但是,调用数据库以在迁移过程中更新数据不会完成或引发错误,只是挂起。

我正在尝试向数据库中的现有模型添加registrationType字段。该字段不应为null,因此我需要添加'allowNull:false'属性。尚未设置registrationType的旧注册应使用模型中已存在的数据更新为正确的类型。为此,我需要访问模型中的ID字段,获取链接的对象(指向具有locationtype的位置的注册链接),然后使用该对象来确定registrationType。我在迁移中添加了代码,就好像它是更新某些数据的普通数据库操作一样,但是这些调用不会返回或引发错误。

我不能(也不想)使用默认值,因为应该基于现有数据为每个注册确定该值(添加默认值将使allowNull prop过时)。 我的方法: -添加没有'allowNull'约束的列(使用addColumn) -更新所有现有数据 -添加“ allowNull”约束(使用changeColumn)

"use strict";

/*const db = require("../models");
const Registration = db.Registration;
const Site = db.Site;
const Location = db.Location;
*/
const REGISTATION_MODEL = "Registrations";
module.exports = {
    up: async (queryInterface,Sequelize) => {
        const transaction = await queryInterface.sequelize.transaction();

        try {
            const Registration = await queryInterface.sequelize.import(
                "../models/registration.js"
            );
            const Site = await queryInterface.sequelize.import(
                "../models/site.js"
            );
            const Location = await queryInterface.sequelize.import(
                "../models/location.js"
            );

            await queryInterface.addColumn(
                REGISTATION_MODEL,"registrationType",{
                    type: Sequelize.STRING
                },{ transaction }
            );

            console.log(
                " * Column added,going to update existing registrations."
            );
            const registrations = await Registration.findAll();
            console.log(
                `\tFound ${registrations.length} registrations to be updated.`
            );
            for await (const registration of registrations) {
                const site = await Site.findByPk(registration.SiteId);
                const location = await Location.findByPk(site.LocationId);
                await registration.update(
                    {
                        registrationType: location.locationType
                    },{ transaction }
                );
            }

            console.log(`\tUpdated ${registrations.length} registrations.`);
            console.log(" * Adding 'allowNull:false' to field.");
            //allowNull: false
            await queryInterface.changeColumn(
                REGISTATION_MODEL,{ type: Sequelize.STRING,allowNull: false },{ transaction: t }
            );
            await transaction.commit();
        } catch (ex) {
            await transaction.rollback();
            console.error("Something went wrong: ",ex);
        }
    },down: (queryInterface,Sequelize) => {
        return queryInterface.removeColumn(
            REGISTATION_MODEL,"registrationType"
        );
    }
};

输出:

Loaded configuration file "config/config.json".
Using environment "development".
== 20191107134514-add-registration-types: migrating =======
 * Column added,going to update existing registrations.

然后挂起。

此处显示的代码不会产生任何错误,也不会产生任何输出。我添加了console.log语句,并再次运行了迁移,这表明代码在第一个findAll()调用处挂起。 谁能告诉我该怎么做?

qhzy1 回答:在迁移中是否可以使用sequelize更新Postgresql数据库中的现有数据

更新:如chat中所述,我们需要将addColumn,changeColumn和更新查询分隔为单独的文件。由于我们无法在同一个事务下运行所有​​这些文件,因为它们会影响相同的表。

如果要在迁移功能中await,则需要使up/down函数异步,并同时使用await和async运行事务:

下面是仅用于更新表的迁移文件。为addColumn和changeColumn创建单独的迁移。按以下顺序运行它们:

  1. 添加列
  2. 更新表
  3. 更改列

用于表更新的迁移:

up: async (queryInterface,Sequelize) => {
    // declare transaction outside try catch so it is available in both
    const transaction = await queryInterface.sequelize.transaction()
    try {
        // No need to use transactions for read operations
        const registrations = await Registration.findAll()

        // using for...of loop which supports awaiting inside it
        for await (const registration of registrations) {
            const site = await Site.findByPk(registration.SiteId)
            const location = await Location.findByPk(site.LocationId)

            // Make sure to await on all sequelize methdos
            await registration.update({ registrationType: location.locationType })
        }

        // Commit transaction if no error occurs
        await transaction.commit()
    } catch (error) {
        // Rollback transaction if error occurs
        await transaction.rollback()
        console.error("Something went wrong: ",ex)
    }
}
本文链接:https://www.f2er.com/3143526.html

大家都在问