我的续集设置遇到了一些困难,正在寻求一些指导/帮助。
我正在处理的场景如下:
简而言之,sqlite 是“离线”工作区域,但是当用户连接到实时系统时,数据需要迁移,但会成为应用程序的工作连接,以便他们可以继续“在线”编辑内容。但是,用户可能决定与实时服务器“断开连接”,因此应用程序需要恢复到 sqlite 数据库。
实时服务器是“可配置的”,因此可能需要创建多个“实时”连接,因此我无法在启动时创建它,然后永远保留它,用户可以在两个不同的实时服务器之间切换。
但是,由于实时数据库和离线数据库都是彼此的副本,因此我有一组模型定义,并且希望在连接/断开连接时基本上“交换”续集连接。这就是我现在所拥有的:
'use strict';
const {
app,
} = require('electron');
const logger = require('electron-log');
const path = require('path');
const {
Sequelize, Op,
} = require('sequelize');
const userData = app.getPath('userData');
const dbFile = path.resolve(userData, 'library_v2.sqlite');
logger.debug(dbFile);
import {
SequelizeStorage, Umzug,
} from 'umzug';
const db = {
};
// Define the 'default' sqlite connection:
const sequelize = new Sequelize({
dialect: 'sqlite',
retry: {
max: 50,
},
storage: dbFile,
logging: msg => logger.debug(msg),
});
// Init the mssql connection:
let mssqlConnection = null;
// This is my connect function which works:
export const connect = (config, data) => {
mssqlConnection = new Sequelize(config.database, config.username, config.password, {
dialect: 'mssql',
retry: {
max: 5,
},
host: config.host,
port: config.port,
logging: msg => logger.debug(msg),
});
Object.values(db.sequelize.models)
.forEach(model => {
// Swap out the sequelize connection:
model.sequelize = mssqlConnection;
});
...
db.sequelize = mssqlConnection;
db.Sequelize = Sequelize;
db.Op = Op;
...
// Run the migration and seeds:
const check = initialiseDatabase(mssqlConnection);
return check.then(() => {
return true;
});
};
// This is my disconnect function which doesn't work... maybe...
export const disconnect = async () => {
console.log('Disconnecting');
await mssqlConnection.close();
...
PT = null;
mssqlConnection = null;
// Reset the sequelize to the sqlite:
Object.values(db.sequelize.models)
.forEach(model => {
model.sequelize = sequelize;
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
db.Op = Op;
...
return true;
};
...
// Staging models:
db.Modules = require('./modules')(sequelize, Sequelize.DataTypes);
db.Sequences = require('./sequences')(sequelize, Sequelize.DataTypes);
...
Object.keys(db)
.forEach(async (modelName) => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
...
db.sequelize = sequelize;
db.Sequelize = Sequelize;
db.Op = Op;
...
export default db;
连接似乎工作正常,我可以使用新连接来处理数据,但是当我尝试断开连接时,据我所知,一切都已“重置”以使用原始 sqlite 数据库,但出现错误抛出:
Error: ConnectionManager.getConnection was called after the connection manager was closed!
at ConnectionManager.getConnection ([...]/node_modules/sequelize/lib/dialects/abstract/connection-manager.js:74:13)
at [...]/node_modules/sequelize/lib/sequelize.js:305:111
at [...]/node_modules/retry-as-promised/dist/index.js:59:25
at new Promise (<anonymous>)
at retryAsPromised ([...]/node_modules/retry-as-promised/dist/index.js:48:12)
at Timeout._onTimeout ([...]/node_modules/retry-as-promised/dist/index.js:94:21)
at listOnTimeout (node:internal/timers:569:17)
at process.processTimers (node:internal/timers:512:7)
从我的调试来看,我非常确定一切都已完成,但一旦我尝试从 sqlite 数据库“获取”数据,它就会抛出此错误。因此,似乎存在一个杂散的承诺,直到断开连接后才完成。
我已经检查了断开连接后“获取”新数据的模型,它显示了正确的续集连接 - 数据库的方言和文件 - 所以我相当确定它已断开连接。但是,获取失败,然后应用程序停止从数据库加载任何内容 - 所有模型的每次获取都报告相同的错误。唯一的解决方案是终止该应用程序并重新启动它。
有人知道我可能会错过什么吗?
注意:我已经稍微精简了代码,以删除大部分模型、使用 umzug 的迁移和播种器,以及一些续集修订跟踪(这些都有效,所以不认为它们是必要的),但没有编译错误。如果您认为可能还有其他原因,如果您认为需要,很乐意提供更多内容。
经过多次尝试和错误,我偶然发现了“解决方案”,它可以归结为“顺序”。
为了使其正常工作,断开连接功能需要是:
// This is my disconnect function which doesn't work... maybe...
export const disconnect = async () => {
// Apparently this needs to be before the .forEach:
db.sequelize = sequelize;
db.Sequelize = Sequelize;
db.Op = Op;
// Reset the sequelize to the sqlite:
Object.values(db.sequelize.models)
.forEach(model => {
model.sequelize = sequelize;
});
console.log('Disconnecting');
await mssqlConnection.close();
...
PT = null;
mssqlConnection = null;
...
return true;
};
我不完全确定为什么这是有效的答案 - 我猜测在旧连接断开之前需要将模型重新分配给 sqlite 续集。否则,看起来他们会陷入某种困境,模型不确定连接到底是什么,并尝试使用断开的 mssql 连接。