I'm using GraphJS with sequelize, when I defined a unique column in the model:
const Product = Connection.define('Product', {
label: {
type: Sequelize.STRING,
allowNull: false,
unique: true <--------------
},
description: {
type: Sequelize.TEXT,
allowNull: false
},
price: {
type: Sequelize.FLOAT(6, 3),
}
});
when I try to insert the second row with the same label :
const Mutations = new GraphQLObjectType({
name: 'Mutations',
description: 'All Mutations',
fields: () => {
return {
addProduct: {
type: Product,
args: {
new: {
name: 'New product',
type: ProductInput
}
},
resolve(_, args) {
return Db.models.Product.create(args.new);
}
},
};
}
});
I got the following error:
TypeError: Cannot read property '2' of null
Any ideas ?
you dont seem to be the only one having the problem:
https://github.com/sequelize/sequelize/issues/6725
https://github.com/feathersjs-ecosystem/feathers-sequelize/issues/71
do you also use mysql, and if yes which version?
seems to work in some versions, and in some not:
https://github.com/feathersjs-ecosystem/feathers-sequelize/issues/71#issuecomment-255192417
Related
Hope you're well !
I have a question. How can I prevent the following error after a db reset (sync force true) please ?
SequelizeDatabaseError: type "enum_coverLists_supportingDocument"
already exists
Here is what my model look like :
export const SUPPORTING_DOCUMENT = {
MEDIATION_FEES: 'MEDIATION_FEES',
LEGAL_COUNSEL_FEES: 'LEGAL_COUNSEL_FEES',
FILING_COMPLAINT: 'FILING_COMPLAINT'
};
export const TYPE = {
BUDGET: 'BUDGET',
QUANTITY: 'QUANTITY',
UNLIMITED: 'UNLIMITED'
};
const coverList = function (sequelize, Sequelize) {
const coverList = sequelize.define('coverList',
{
id: {
primaryKey: true,
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV4
},
title: {
type: Sequelize.STRING,
allowNull: false
},
description: {
type: Sequelize.STRING,
allowNull: true
},
supportingDocument: {
type: Sequelize.ARRAY(Sequelize.ENUM({
values: [...Object.values(SUPPORTING_DOCUMENT)]
})),
validate: {
isIn: [...Object.values(SUPPORTING_DOCUMENT)],
},
allowNull: true
},
type: {
type: Sequelize.ENUM,
values: Object.values(TYPE),
validate: {
isIn: [Object.values(TYPE)],
},
allowNull: false
}
});
return coverList;
};
export default coverList;
Stack :
Node.js
PostgreSQL
Sequelize
Thanks in advance for your help.
So, Whenever you create an "enum" it will store in the database. if you are using pgAdmin it stores all enums in the "Types" folder and if you use dbeaver there it is stored in "dataTypes" folder. so from there, you can delete it...
you can see here...
I'm getting this range error for a value I am not inserting.
const createTransaction = async (yodleeAccountId, transaction) => {
try {
const savedRecord = await YodleeTransaction.create({
YodleeAccountID: 373,
YodleeID: 1887219837,
Amount: 40518.32,
AmountCurrency: 'USD',
BaseType: 'CREDIT',
Container: 'bank',
PostDate: '2016-03-19',
OriginalDescription: 'info about transaction',
SimpleDescription: 'info',
CategoryID: '2',
Category: 'giving idk',
CategoryType: 'the important type',
})
console.log('post create')
return savedRecord
} catch (error) {
console.error('error finally caught', error)
return error
}
}
YodleeTransaction model:
module.exports = (sequelize, type) => {
return sequelize.define(
'YodleeTransaction',
{
ID: { type: type.BIGINT, primaryKey: true, autoIncrement: true },
YodleeAccountID: { type: type.BIGINT, allowNull: false },
YodleeID: { type: type.BIGINT, allowNull: false },
Amount: { type: type.DECIMAL(12, 2), allowNull: false },
AmountCurrency: { type: type.STRING(3) },
BaseType: { type: type.STRING(25), allowNull: false },
Container: { type: type.STRING(50) },
PostDate: { type: type.DATE, allowNull: false },
OriginalDescription: { type: type.STRING(800) },
SimpleDescription: { type: type.STRING(500) },
CategoryID: { type: type.INTEGER },
Category: { type: type.STRING(50) },
CategoryType: { type: type.STRING(50) },
},
{ freezeTableName: true, tableName: 'YodleeTransaction' }
)
}
Error:
RangeError [ERR_OUT_OF_RANGE]: The value of "value" is out of range. It must be >= 0 and <= 4294967295. Received 9433906525
I know that 9433906525 is somehow based on the Amount because when I change the Amount, the value in the error message changes.
For example if I change Amount from 40518.32 to 8989.33 the new value received is 10728568304.
New error:
RangeError [ERR_OUT_OF_RANGE]: The value of "value" is out of range. It must be >= 0 and <= 4294967295. Received 10728568304
This appears to be a bug in Sequelize.
Doing too many insertions or updates asynchronously causes this to happen.
I don't know specifically how to resolve this issue, but I can tell you how to get around it.
The solution to the above create error is to use bulkCreate and pass it an array of objects.
If you are doing updates with t-sql then Sequelize does not provide a bulkUpdate methods. So you should just manually write out the update query inside sequelize.query('UPDATE YodleeTransaction SET Amount=344.88').
I am using sequelize and SQLite3. When I use the model in my code then it is generating wrong query. Can any one help me to fix this issue
This is my model defiantion
module.exports = function(sequelize, DataTypes) {
let product = sequelize.define('product', {
id: {
type: DataTypes.INTEGER(10).UNSIGNED,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING(200),
},
code: {
type: DataTypes.STRING(100),
},
desc: {
type: "BLOB",
},
productCategoryId: {
type: DataTypes.INTEGER(10).UNSIGNED,
references: {
model: 'product_category',
key: 'id'
}
},
costPrice: {
type: DataTypes.FLOAT,
},
sellPrice: {
type: DataTypes.FLOAT,
},
markup: {
type: DataTypes.FLOAT,
},
markupType: {
type: DataTypes.ENUM('AMOUNT','PERCENTAGE'),
},
imgAttachment: {
type: DataTypes.INTEGER(1),
},
minOrderQuantity: {
type: DataTypes.INTEGER(10),
},
minStockQuantity: {
type: DataTypes.INTEGER(10),
},
isComposite: {
type: DataTypes.INTEGER(1),
},
isAllowedOutOfStockSale: {
type: DataTypes.INTEGER(1),
defaultValue: '0'
},
isActive: {
type: DataTypes.INTEGER(1),
defaultValue: '0'
},
isDeceptive: {
type: DataTypes.INTEGER(1),
defaultValue: '0'
},
createdAt: {
type: DataTypes.DATE,
},
createdBy: {
type: DataTypes.INTEGER(10).UNSIGNED,
references: {
model: 'user',
key: 'id'
}
},
deletedAt: {
type: DataTypes.DATE,
},
deletedBy: {
type: DataTypes.INTEGER(10).UNSIGNED,
references: {
model: 'user',
key: 'id'
}
},
updatedAt: {
type: DataTypes.DATE,
},
updatedBy: {
type: DataTypes.INTEGER(10).UNSIGNED,
references: {
model: 'user',
key: 'id'
}
}
}, {
tableName: 'product',
timestamps: false,
defaultScope: {
where: {
isActive: true,
deletedAt: null,
}
}
});
// Association
product.associate = function(models) {
models.product.belongsTo(models.user);
models.product.belongsTo(models.user);
models.product.belongsTo(models.user);
models.product.belongsTo(models.product_category);
models.product.hasMany(models.product_composition);
};
return product;
}
This is my model implementation
models.findAll({})
.then(data => {
console.log(data)
.catch(err => {
console.log(err)
});
I am getting SequelizeDatabaseError. After investigation I trace out the generated query
SELECT `id`, `name`, `code`, `desc`, `productCategoryId`, `costPrice`, `sellPrice`, `markup`, `markupType`, `imgAttachment`, `minOrderQuantity`, `minStockQuantity`, `isComposite`, `isAllowedOutOfStockSale`, `isActive`, `isDeceptive`, `createdAt`, `createdBy`, `deletedAt`, `deletedBy`, `updatedAt`, `updatedBy`, `userId` FROM `product` AS `product` WHERE `product`.`id` = 1 AND `product`.`isActive` = 1 AND `product`.`deletedAt` IS NULL;
Why it is adding userId in query. This query works fine when I remove userId field from this generated query
That is because of this line :
This line will add a userId attribute to product to hold the primary key value for Product
models.product.belongsTo(models.user);
But This will not add the field , reason is , naming convention is followed for foreign key name productCategoryId but not in above case ,
models.product.belongsTo(models.product_category);
for that you should define that explicitly and you should also add alias name for association coz you are using one table for 3 relations , like
models.product.belongsTo(models.user , { as : 'delete_by' ,foreignKey: 'deletedBy'} );
models.product.belongsTo(models.user , { as : 'created_by' ,foreignKey: 'createdBy'} );
models.product.belongsTo(models.user , { as : 'updated_by' , foreignKey: 'updatedBy'} );
For more detail : DO READ
I'm using Sails v0.11.2 and MongoDB 3.2 on Mac OS X El Capitan and I'm trying to implement Many-To-Many association using Through option which isn't supported yet.
However, googling I found this Waterline Github Issue and elennaro, a github user, gave me a couple of links with some examples:
First one
Second one
I have tried to adapt them to my own Sails app but I can't make it works. I got no errors on the console but the record or document on the intermediary table is not created only the Form document in it's table.
These are my models:
User.js
module.exports = {
schema: true,
tableName: 'users',
autoCreatedAt: false,
autoUpdatedAt: false,
attributes:
{
email : { type: 'email', required: true, unique: true },
encrypted_password : { type: 'string' },
reset_password_token: { type: 'string', defaultsTo: null},
permission_level : { type: 'integer', required: true, min: 1, max: 3, defaultsTo: 0 },
belongs_to : { type: 'string', required: true, defaultsTo: 0 },
signin_count : { type: 'integer', required: true, defaultsTo: 1 },
status_active : { type: 'boolean', required: true, defaultsTo: false },
last_signin_at : { type: 'datetime', defaultsTo: function (){ return new Date(); } },
last_signin_ip : { type: 'string', defaultsTo: '0.0.0.0' },
// Add a reference to Person
person_id:
{
model: 'person'
},
// Add a reference to Forms collection
forms:
{
collection: 'form',
via: 'user_id',
through: 'userhasform'
},
has:
{
collection: 'userhasform',
via: 'form_id'
}
}
};
Form.js
module.exports = {
schema: true,
tableName: 'forms',
attributes:
{
name : { type: 'string', required: true, unique: true },
creator : { type: 'string', unique: false },
sequence: { type: 'integer', autoIncrement: true },
// Add a reference to Questions collection
questions:
{
collection: 'question',
via: 'form_id'
},
// Add a reference to the owners Users
owners: {
collection: 'user',
via: 'form_id',
through: 'userhasform'
}
}
};
UserHasForm.js
module.exports = {
schema: true,
tableName: 'users_have_forms',
attributes:
{
to_edit : { type: 'boolean' },
to_delete : { type: 'boolean' },
user_id : { model: 'user' },
form_id : { model: 'form' }
}
};
The controller in which I create a form and it is supposed the intermediary document is been created at the join table is:
FormController.js
module.exports = {
create: function (req, res)
{
var ownerJson = {},
tmpFolio;
// Get the logged user to make the Folio and then create the form
SessionService.getUser(req, createForm);
// Callback function
function createForm (err, session)
{
// If there's no logged user or any error
if (err || !session)
{
console.log(err);
return res.json(err.status, {error: err});
}
console.log('User to create Folio: ', session.id);
ownerJson.owner_a = session.first_name;
ownerJson.owner_b = session.second_name;
ownerJson.owner_c = session.last_name;
// Construct the Folio creator part like AVC
tmpFolio = FolioService.generateFolio(ownerJson);
Form.create({
name: req.body.name,
creator: tmpFolio
})
.then(function (form){
if (err)
{
console.log(err);
return res.json(err.status, {error: err});
}
// Create the jointable record
var createdRecord = UserHasForm.create({
to_edit: true,
to_delete: true,
user_id: session.id,
form_id: form.id
})
.then(function (createdRecord){
if (err)
{
console.log(err);
return res.json(err.status, {error: err});
}
return createdRecord;
});
return [form, createdRecord];
})
.spread(function (form, createdRecord){
return res.json(200,
{
message: 'The form was created successfuly!',
data: form,
sharing: createdRecord
});
})
.fail(function (err){
if (err)
{
console.log(err);
res.json(err.status, {error: err});
}
});
}
},
};
When I run this code I got the next error:
[ReferenceError: UserHasForm is not defined]
Unhandled rejection TypeError: Cannot read property 'toString' of undefined
So I suppose it can't find the model so I add the next line to the model at the beginning:
var UserHasForm = require('../models/UserHasForm');
And now I get the next error:
[TypeError: UserHasForm.create is not a function]
All this is following the the first example on the list.
Any idea why I'm getting this error?
Any kind of help will be welcomed!
Well after trying to many examples finally I found the solution thanks to #elennaro for all his support. The whole conversation could be found in the link to the chat we both started under the main question's comments.
Also I can tell you that the examples in the links provided by him (which are in the question above) works fine, the problem was that the version I was using didn't support the features that those examples show.
Basically what I had to do is to install the most recent version for NodeJS, SailsJS and Waterline.
In my case I actually have the next ones:
Node v5.3.0
Sails v0.11.3
Waterline v0.10.30
After that I have to make some changes to my models and at the end they look like this:
User.js
module.exports = {
schema: true,
tableName: 'users',
autoCreatedAt: false,
autoUpdatedAt: false,
attributes:
{
// username : { type: 'string', unique: true, minLength: 5, maxLength: 15 },
email : { type: 'email', required: true, unique: true },
encrypted_password : { type: 'string' },
reset_password_token: { type: 'string', defaultsTo: null},
permission_level : { type: 'integer', required: true, min: 1, max: 3, defaultsTo: 0 },
belongs_to : { type: 'string', required: true, defaultsTo: 0 },
signin_count : { type: 'integer', required: true, defaultsTo: 1 },
status_active : { type: 'boolean', required: true, defaultsTo: false },
last_signin_at : { type: 'datetime', defaultsTo: function (){ return new Date(); } },
last_signin_ip : { type: 'string', defaultsTo: '0.0.0.0' },
// Add a reference to Forms collection
forms:
{
collection: 'form',
via: 'user',
through: 'userhasform'
// dominant: true
}
}
};
Form.js
module.exports = {
schema: true,
tableName: 'forms',
attributes:
{
name : { type: 'string', required: true, unique: true },
creator : { type: 'string', unique: false },
sequence: { type: 'integer', autoIncrement: true },
// Add a reference to the owners Users
owners: {
collection: 'user',
via: 'form',
through: 'userhasform'
}
}
};
UserHasForm.js
module.exports = {
schema: true,
tableName: 'users_have_forms',
attributes:
{
to_edit : { type: 'boolean' },
to_delete : { type: 'boolean' },
user : { model: 'User', foreignKey: true, columnName: 'user_id' },
form : { model: 'Form', foreignKey: true, columnName: 'form_id' }
}
};
FormController.js
Still the same as in the question
I hope it could be useful for anybody. And once again thanks to # Alexander Arutinyants for your support!
Any question, please leave a comment!
I'm newbie of Sails and I've got a problem with one to one association.
First, I have model User:
module.exports = {
schema: true,
identity : "User",
tableName: "user",
attributes: {
email: {
type: 'email',
unique: true,
required: true
},
password: {
type: 'string'
},
salt: {
type: 'string'
},
merchant: {
model: 'merchant',
defaultsTo: null
},
removed: {
type: 'boolean',
required: true,
defaultsTo: false
}
}
}
And my Merchant model:
module.exports = {
schema: true,
identity : "Merchant",
tableName: "merchant",
attributes: {
name: {
type: 'string',
unique: true,
required: true
},
code: {
type: 'string',
unique: true,
required: true
},
security_key: {
type: 'string',
required: true
},
active: {
type: 'boolean',
defaultsTo: false,
required: true
},
user: {
model: 'user'
}
}
}
So when I need to find records where merchant.active = true, I write this query:
var findUser = User.find(query).populate('merchant', {active: true});
return findUser;
But it was not working at all.
Anyone any ideas to solve this properly?
P.S. my Sails version is: 0.11.1. My DB is MongoDB
First of all, remove defaultsTo from your association attributes. I don't like this :) I don't know if it makes the problem, but in documentation I never see this.
Also you need to execute your query, not just return it. If I take your models' declarations then I can write populate query like this.
var findUser = User.find(query).populate('merchant', {active: true});
findUser.then(function(user) {
console.log('Your user is ' + user);
}).catch(function(error) {
console.log('Your error is ' + error);
});