我正在尝试使用序列化/乏味性通过CRUD操作访问Azure SQL数据库。我在其中一张表中有一个长字符串(签名)。
CREATE TABLE [dbo].[Owner](
[OwnerId] [int] PRIMARY KEY IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL,
[Signature] [varchar](max) NULL
)
这是我的续集模型:
/* owner.js */
export default function(sequelize, DataTypes) {
var Owner = sequelize.define(
'Owner',
{
ownerId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
field: 'OwnerId',
},
name: {
type: DataTypes.STRING(50),
validate: {
notEmpty: true,
},
allowNull: false,
field: 'Name',
},
signature: {
type: DataTypes.STRING(50000),
validate: {
notEmpty: true,
},
allowNull: true,
field: 'Signature',
},
},
{
schema: 'dbo',
timestamps: false,
freezeTableName: true,
}
);
return Owner;
}
这是读取和创建记录的代码:
/* index.js */
import Sequelize from 'sequelize';
var db = {};
var sequelize = new Sequelize('mydb', 'developer', 'mypassword', {
host: 'mydevserver.database.windows.net',
dialect: 'mssql',
pool: {
max: 5,
min: 0,
idle: 10000
},
dialectOptions: {
options: {
encrypt: true
}
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
var model = sequelize['import']('./owner.js');
db[model.name] = model;
/* Find a record with long signature (8000 chars) is fine. */
db.Owner.findByPk(6)
.then(o => {
console.log(`Found owner ${o.name}, with signature ${o.signature}.`);
})
// let s = '0123456789'.repeat(100); /* This is ok. Record created. */
let s = '0123456789'.repeat(500); /* This gives error 'read ECONNRESET' */
db.Owner.create({
name: 'Rick',
signature: `${s}`
})
.then(newOwner => {
console.log(`New owner ${newOwner.name}, with id ${newOwner.ownerId} has been created.`);
}).catch(function (error) {
console.log(error.message);
});
我正在使用
"sequelize": "^5.10.1",
"tedious": "^6.2.0"
我知道可以输入的字符串会有限制,但是5000字符的字符串并不长。
有什么想法吗?这是错误的堆栈跟踪
Unhandled rejection SequelizeDatabaseError: read ECONNRESET
at Query.formatError (C:\work\GitRepos\sequelize-test\node_modules\sequelize\lib\dialects\mssql\query.js:309:12)
at Request.userCallback (C:\work\GitRepos\sequelize-test\node_modules\sequelize\lib\dialects\mssql\query.js:69:23)
at Request.callback (C:\work\GitRepos\sequelize-test\node_modules\tedious\lib\request.js:37:27)
at Connection.socketError (C:\work\GitRepos\sequelize-test\node_modules\tedious\lib\connection.js:2157:20)
at Connection.dispatchEvent (C:\work\GitRepos\sequelize-test\node_modules\tedious\lib\connection.js:1172:36)
at Connection.socketError (C:\work\GitRepos\sequelize-test\node_modules\tedious\lib\connection.js:1190:10)
at Socket.<anonymous> (C:\work\GitRepos\sequelize-test\node_modules\tedious\lib\connection.js:1032:14)
at Socket.emit (events.js:205:15)
at Socket.EventEmitter.emit (domain.js:471:20)
at emitErrorNT (internal/streams/destroy.js:91:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)
at processTicksAndRejections (internal/process/task_queues.js:84:9)
更新:
如果我增加了连接的数据包大小,
dialectOptions: {
options: {
encrypt: true,
packetSize: 32768
}
}
然后问题解决了。即使我将字符串的长度增加到更大的数字,例如
let s = '0123456789'.repeat(500000);
它仍然有效。这对我来说没有意义。在服务器端,为什么当数据包大小为4096(默认值)时不重新组装数据包,但是在更大的数据包大小时,为什么要重新组装数据包。同样在客户端,无论包大小如何,都始终会重新组装包。
答案 0 :(得分:0)
这似乎是Tedious中的bug,已在6.2.1中修复。当我在Azure中切换NodeJS应用程序以使用NodeJS 12时,我遇到了它。
上面提到的有关增加数据包大小的变通方法确实有效,这是我实现的,因为我正在使用Sequelize 4,并且不确定当前的Tedious版本是否兼容(我似乎记得在您需要某个版本的网络才能使Sequelize 4满意)。