sequelize: findOrCreate fails concurrently when unique attribute contains comma in value. Postgres unique constraint error incorrectly parses error message 23505 when the value contains a ','.
What you are doing?
Trying to concurrently use findOrCreate when an attribute set to unique, would contain a comma.
'use strict';
const Sequelize = require('sequelize');
//first connect to the database
const database = new Sequelize('database', 'user', 'password', {
dialect: 'postgres',
host: '127.0.0.1',
port: 5432,
pool: {
max: 5,
min: 0,
idle: 10000
},
});
return database.authenticate()
.then(() => {
//success connecting,
console.log('database connected');
return database;
})
.then(database => {
const containerModel = database.define('TestContainer', {
name: {
type: Sequelize.DataTypes.STRING(32),
allowNull: false,
unique: 'name',
},
});
return database.sync({
alter: true,
force: false,
})
.then(database => {
return database.transaction({
autoCommit: false,
})
.then(transaction => {
return Promise.all(['hello, world', 'hello, world'].map(name => {
console.log(`findOrCreate({name: '${name}'})`);
return containerModel.findOrCreate({
where: {
name: name,
},
defaults: {
name: name,
},
transaction: transaction,
returning: true,
});
}))
.then(() => {
transaction.rollback();
})
.catch(() => {
transaction.rollback();
});
});
});
})
.catch(err => {
//failed to connect
console.error(err);
process.exit(1);
});
What do you expect to happen?
concurrent operations to succeed without fail!
What is actually happening?
So lets say i set attribute of my Model attribute ‘name’ to unique. If i were to try and findOrCreate multiple of these models concurrently, and there is a unique validation error, then it fails!
It fails because the findOrCreate checks the fields in the err object generated by postgres/query.js. The parsing of said fields is done from the error message generated by postgres. In the postgres/query.js it is splitting the regex matched values by ‘,’ for both the field name and value. This incorrectly truncates the field value if it contained a ‘,’. When the findOrCreate attempts to check for concurrency, it fails because the reported value from the error and the value its expecting do not match!
Get an error of
TestContainer#findOrCreate: value used for name was not equal for both the find and the create calls, ‘hello, world’ vs ‘hello’
Dialect: postgres Database version: 9.6 Sequelize version: master
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 5
- Comments: 17 (6 by maintainers)
Experiencing the same issue with PG 10.3. In addition to that, I have a similar issue with PostGIS fields (geography(Point,4326)) and findOrCreate
Here is a list of all coordinates that fail with the above error:
‘0101000020E61000001E1B81785DCF2940A835CD3B4E694940’ ‘0101000020E610000013D6C6D809572A40069FE6E4453E4A40’ ‘0101000020E61000000C59DDEA39592B4006BB61DBA2284A40’ ‘0101000020E6100000F38E537424EF2340C6A70018CFC64A40’ ‘0101000020E6100000ED647094BC7A2240B97020240B0C4940’ ‘0101000020E61000002EE23B31EBF52140C32ADEC83C2E4840’ ‘0101000020E6100000CA54C1A8A47E294073F4F8BD4D1F4840’ ‘0101000020E61000006902452C626833409DF4BEF1B51D4B40’ ‘0101000020E6100000594C6C3EAE4D2B40349D9D0C8E424A40’ ‘0101000020E6100000834C327216D61C40780B24287EC44940’ ‘0101000020E61000007767EDB60B1D2140E36BCF2C09144940’ ‘0101000020E6100000C53D963E74312C40F9A067B3EA834940’ ‘0101000020E6100000626534F2792D2D40F566D47C955E4940’
Having the same issue with Postgres. I created a Model that contains only id (unique, int, auto-increment) and message (text). Here are my findings:
This issue is also occurring for MySQL, with
/
present for in the value for an attribute with unique constraint. In my case, it seems to be doing something different.For example if I were to pass following values to findOrCreate:
I would get the error:
(Note that it is comparing the values passed for uniqueStringParameter and uniqueIntegerParameter)
This is also difficult to reproduce since it only happens when findOrCreate runs concurrently.
Should I open a new issue for this?
still a problem fwiw
@idris Can you please convert that to a complete MVCE that I can copy-paste and run? Thanks!
By the way, this same issue happens with
)
in the string as well as,