I am using sequelize in my application. I have postgres as underlying database.
But when I tried to save instances I got following error
[error: missing dimension value]
I have the following model
module.exports = function(sequelize, DataTypes) {
var Mymodel = sequelize.define('Mymodel', {
id: {type : DataTypes.INTEGER, autoIncrement : true, primaryKey: true},
title: {
type: DataTypes.STRING(128),
validate: {
notNull: true,
notEmpty: true
}
},
tags: DataTypes.ARRAY(DataTypes.TEXT)
});
return Mymodel;
}
I am sending http post request as
{
"title":"Test challenge",
"tags" : "['JAVA','REST','API']"
}
I am saving object like this
Mymodel.create(model).success(function(model) {
callback(null, challenge);
}).error(function(err) {
callback(err, null);
});
I tried sending over your model object as you stated and did get the error SequelizeValidationError: "['JAVA','REST','API']" is not a valid array. Perhaps you got a different error on an older version of Sequelize. Then, I made sure the tags value was a JavaScript array instead of a string and it worked.
Mymodel.create({
title: 'Test challenge',
tags: ['JAVA','REST','API']
}).then(function() {});
Related
So I'm trying to access this account by using the findOne function in mongoose, and I'm trying to console.log the error, but the error is just the correct model found.. once I find the correct model I want to access one of the nested objects in the schema so I can edit the value.
I'm not sure why this is happening, below I put the code as well as the error that was logged into the console, I can provide more if needed.
let accountSchema = mongoose.Schema({
username:{
type: String,
required: true,
index: true,
unique: true,
},
password:{
type: String,
required: true,
},
money:{
type: Number,
},
inventory: { type: [{
weed: { type: Number },
coke: { type: Number },
}]},
});
mp.events.addCommand('coke', (player) => {
console.log(player.name);
Account.findOne({username: 'a'}, function(acc, err) {
if(err) return console.log(err);
console.log(acc.username);
acc.inventory[1] = acc.inventory[1] + 1;
acc.save(function(err){
if(err) return player.outputChatBox('Not logged in');
player.outputChatBox('Added 1 coke');
});
});
});
(Console) {"_id":"5b6acbbbc285477e39514cb9","username":"a","password":"$2a$10$XABqooqFRINYVdJ79.i2E.5xdpitRrfZxUBmIPAZjjaXKvvLDc2y2","money":5000,"inventory":[{"_id":"5b6acbbbc285477e39514cbb","weed":0},{"_id":"5b6acbbbc285477e39514cba","coke":0}],"__v":0}
The callback function for the .findOne method has the following signature:
function (err, obj) {
}
You are using the arguments in the wrong order - the error object is the first argument and the object found is the second one.
The .findOne method callback must have the following parameters function (err, res). So you are setting them in a reversed order.
Check http://mongoosejs.com/docs/api.html#model_Model.findOne
I am getting started with Sequelize. I am following the documentation they are providing on their website :http://docs.sequelizejs.com/manual/installation/getting-started.html
const Sequelize = require('sequelize');
const sequelize = new Sequelize('haha', 'postgres', 'postgres', {
host: 'localhost',
dialect: 'postgres',
operatorsAliases: false,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
// SQLite only
storage: 'path/to/database.sqlite'
});
sequelize
.authenticate()
.then(() => {
console.log('Connection has been established successfully.');
})
.catch(err => {
console.error('Unable to connect to the database:', err);
});
const User = sequelize.define('user', {
firstName: {
type: Sequelize.STRING
},
lastName: {
type: Sequelize.STRING
}
});
// force: true will drop the table if it already exists
User.sync({force: true}).then(() => {
// Table created
return User.create({
firstName: 'John',
lastName: 'Hancock'
});
});
Up until here, everything works perfectly. And the table "user" is correctly built and populated. (Although I do not understand Sequelize appends an "s" automatically to "user", any explanation.)
However when I add the following portion of code:
User.findAll().then(users => {
console.log(users)
})
I get this error :
Unhandled rejection SequelizeDatabaseError: relation "users" does not
exist
So my questions are:
Why does Sequelize add an "s" to user. (I know it makes sense but shouldn't the developer decide that)
What is causing that error? I followed the documentation but it still didn't work?
When you are defining your model you can add configurations, in this case the option that you must add is freezeTableName prevents the names from being plural.
const User = sequelize.define('user', {
firstName: {
type: Sequelize.STRING
},
lastName: {
type: Sequelize.STRING
}
}, {
// disable the modification of table names; By default, sequelize will automatically
// transform all passed model names (first parameter of define) into plural.
// if you don't want that, set the following
freezeTableName: true,
});
There is another interesting way you can avoid this. But you need to really focus on this way of implementation.
const User = sequelize.define("user", {
firstname: {
type: Sequelize.STRING
},
lastname: {
type: Sequelize.STRING
}
});
you intentionally put user here and use users in other places of coding(Assume sequelize will automatically transform all passed model names (first parameter of define) into plural) . This way of coding will simplify your code.
This problem occurs because creating a table is an asynchronous function. The problem is, the findAll() function can get executed while the table has not been created.
to solve this, you can use:
(async ()=>{
await User.sync({force: true});
// Table created
const users=await User.findAll();
console.log(users);
})();
The problem, in my case, was that the table users was not created. You can create the table manually with CREATE TABLE IF NOT EXISTS (SQL) or add the tableName = "users" in the options object:
export const User = db.define('user',
{
id: {
type: DataTypes.UUIDV4,
autoIncrement: true,
primaryKey: true,
},
name: {
type: new DataTypes.STRING(128),
allowNull: false,
},
email: {
type: new DataTypes.STRING(128),
allowNull: true,
},
password: {
type: new DataTypes.STRING(128),
allowNull: true,
},
},
{
freezeTableName: true,
tableName: "users"
}
);
Run that code twice.
Before running the second time, comment out the following code,
// force: true will drop the table if it already exists
User.sync({force: true}).then(() => {
// Table created
return User.create({
firstName: 'John',
lastName: 'Hancock'
});
});
Maybe answer is not entirely connected with you question but I want to describe my experience with this error
Error: relation "users" does not exist.
It appears Sequelize make migrations based on migrations file names and it alphabetical order. My problem was my files naming was not sorted in order to create proper connections.
If you face with this problem make sure yours migration files are fired in proper (in alphabetically) order.
The proper order is to first migrate table without connections (eg. table_A) and then tables with connections to table_A.
As I said this may not be answer for your particular order but I want to share my experiences because I didn't find this information on the internet when I was looking for this error.
Simply append tableName: "Users" to your model configuration.
The easiest way I found to solve, is to explicitly set the tableName on the model. As others have mentioned, sequelize defaults to the plural form of a model as the table name. For instance User, becomes Users.
When you query, sequelize looks after a table with the same name as your model User. By defining the tableName in the model, sequelize should search the correct table. Append tableName: "Users" to your model configuration i.e:
User.init(
{
email: DataTypes.STRING,
password: DataTypes.STRING,
role: DataTypes.INTEGER,
},
{
sequelize,
modelName: 'User',
tableName: 'Users',
}
);
If you want Sequelize to use a singular word ('info') for a model and that same singular word for the table ('info'), you can name the model 'info' and also add tablename: 'info' to the definition of your model.
This is a way to control Sequelize's default behavior of pluralizing model names, or not, on a table-by-table basis.
info.js
module.exports = (sequelize, DataTypes) => {
const info = sequelize.define('info', {
firstname: DataTypes.STRING,
email: DataTypes.STRING,
phone: DataTypes.STRING,
}, {
tableName: 'info'
});
return info;
};
I am having a problem with the user model that I'm using with Mongoose and MongoDB to create each profile in my database. It works fine to post one user, but throws the following error if I logout and try again:
{
"name": "MongoError",
"message": "E11000 duplicate key error collection: CourtAPIDev.users index: trackers.case_id_1 dup key: { : null }",
"driver": true,
"index": 0,
"code": 11000,
"errmsg": "E11000 duplicate key error collection: CourtAPIDev.users index: trackers.case_id_1 dup key: { : null }"
}
According to mongoose documentation: If there is more than one document (a second user) without a value for the indexed field or is missing the indexed field, the index build will fail with a duplicate key error. I don't know how to set this _id property for the trackers property –– I thought it generated automatically!
Here's the trackers part of my Schema. And the relevant case_id property, which seems to be throwing the "null" error.
The whole repository can be found on my Github here, but the likely problem spots are the ones I highlighted, I think. Here's the github link: https://github.com/KingOfCramers/node_login_with_trackers
user model:
const UserSchema = new mongoose.Schema({
email: {
type: String,
required: true,
trim: true,
minLength: 1,
unique: true,
validate: {
validator: (value) => {
return validator.isEmail(value);
},
message: '{VALUE} is not a valid email'
}
},
password: {
type: String,
required: true,
minlength: 6
},
tokens: [{
access: {
type: String,
required: true
},
token: {
type: String,
required: true
}
}],
trackers: {
tweets: [TwitterSchema],
legislation: [LegislationSchema],
court_cases: [CourtCaseSchema]
},
frequency: [EmailSchema]
});
Express route:
app.post("/users", (req,res) => {
var body = _.pick(req.body, ['email', 'password']);
body.frequency = {
alert_time: new Date(),
email: req.body.email
}
var user = new User(body);
user.save().then(() => {
return user.generateAuthToken();
}).then((token) => {
res.header("x-auth", token);
res.send(user);
}).catch((e) => {
res.status(400).send(e);
});
});
Test (mocha):
it("Should post a new user", (done) => {
var email = "uniqueemail#example.com"
var password = "9webipasd"
supertest(app)
.post("/users") // Post request to the /todos URL
.send({
email,
password
})
.expect(200)
.expect((res) => {
expect(res.headers).toIncludeKey('x-auth')
expect(res.body._id).toExist();
expect(res.body.email).toBe(email);
})
.end((err) => {
if(err){
return done(err);
}
User.findOne({email}).then((user) => {
expect(user).toExist();
expect(user.password).toNotBe(password);
done();
}).catch((e) => done(e));
});
});
My guess is that there is an index on CourtCaseSchema.case_id which does not allow duplicates.
I think you could check (in a mongo shell) that with CourtAPIDev.court_cases.getIndexes() (I think your db is named CourtAPIDev and the collection is named court_cases but I am not sure about that).
Also if you clean the test db after each run, that would explain why the tests are passing, since there is no more than one user.
Turns out, it was to do with my mongodb database, not any of my code. After searching around online, I found that if I logged into the mongo shell and then dropped all indexes from the users collection, it solved my problem. Could someone explain why this was causing my program to crash? I think it may have to do with an old user model, but I don't really understand. Thanks!
Even if you have all of your keys as unique=False, you may still get E11000 duplicate key error. So in that case, just follow these steps and check if your error is resolved.
Delete all documents from the collection (e.g. db.collection_name.deleteMany({}))
Drop the COLLECTION (NOT THE DATABASE) (e.g db.collection_name.drop())
Cheers !!
I have the following two tables in Sequelize
const Tokens = sequelize.define("Tokens", {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true
},
active: {
type: DataTypes.BOOLEAN
}
});
and
const User = sequelize.define("Users", {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true
},
first_name: {
type: DataTypes.STRING
}
});
User.associate = models => {
models["Users"].hasMany(models["Tokens"], {foreignKey: 'userID', as: 'tokens_userid'});
};
I'm trying to run the following query in Sequelize.
const token = await db.Tokens.findOne({
where: {
id,
active: true
},
include: ["tokens_userid"]
});
But I'm getting the following error.
Error: Association with alias "tokens_userid" does not exists
My main goal is to get the user based on a Token ID. Now I would just move that association to the User table, but the problem with that later on I will want to get all the tokens for a given User ID. So I will run into this problem either way.
I tried adding the following line, but it was complaining about circular relations or something like that.
models["Tokens"].hasOne(models["User"], {foreignKey: 'userID', as: 'tokens_userid'});
How can I query either the Users or Tokens table and have it populate correctly with the relation?
I was able to solve this by adding the following line to my table.
models["Tokens"].belongsTo(models["User"], {foreignKey: 'userID', as: 'tokens_userid_from_token'});
Basically what I tried before but changed hasOne to belongsTo.
Hopefully this helps someone else.
I am currently working on a project and I am stuck with inserting an item into an array/object in the database. What I am trying to do is to add the id of a 'upvoted' post to an array/list in the 'User' Collection, however, I cannot seem to get it to work.
The code for my schemas is as follows:
// this is a child scheme/sub-document
var uvpSchema = new Schema();
uvpSchema.add({
post: String
});
var dvpSchema = new Schema();
dvpSchema.add({
post: String
});
//main schema
var userSchema = new Schema({
firstname: { type: String, required: true },
lastname: { type: String, required: true },
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
upVotedPosts: [uvpSchema],
downVotedPosts: [dvpSchema],
created_at: Date,
});
And here is the code in my 'routes.js' to insert the id of the post into the array:
var newPush = {
post: postID // postID is a variable that I have already defined
};
User.findOneAndUpdate({username: req.session.user}, {$push: {upVotedPosts: newPush}}, {upsert: true, save: true}, (err, user) => {
if (err) console.log(err);
user.upVotedPosts.push(newPush);
User.save;
res.redirect(req.get('referer'));
console.log(user.upVotedPosts);
});
The error I receive in my terminal is:
{ _id: 595f68b5fadd49105813f8a4 },{ _id: 595f693d3c2c21189004b0a7 },{ _id: 595f70a2df80e0252894551b }
events.js:163
throw er; // Unhandled 'error' event
^
Thanks in advance ;-)
Route.js
User.findOneAndUpdate({username: req.session.user}, {$push: {upVotedPosts: newPush}}, {upsert: true, save: true}, (err, user) => {
if (err) console.log(err);
user.upVotedPosts.push(newPush);
User.save;
res.redirect(req.get('referer'));
console.log(user.upVotedPosts);
});
You dont need to explicitly push, since you pushed using findOneandUpdate - $push
Refer here
Secondly , its
user.save()
and not
User.save
First of all, I'd like to thank everyone's' help ;-)
I finally managed to get it partially working! My problem was that my functions were running asynchronously, causing some problems. I solved this by adding callback functions to each mongoose function.
However, the same error is still being returned, causing the server to crash. Everything else works; the new item is added to the array.
Is there anyway to ignore the error so that the server doesn't crash?