I want to insert username, password, and role. But when I executed my function, the role property won't be executed.
This is my migration file:
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
username: {
type: Sequelize.STRING,
unique: true,
},
password: {
type: Sequelize.STRING,
allowNull: false,
},
role: {
type: Sequelize.STRING,
allowNull: false,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
And this is my function for inserting new data (usermodel.js)
static register = ({ username, password }) => {
const encryptedPassword = this.encrypt(password);
return this.create({ username, password: encryptedPassword, role: 'user' })
}
This is what I got when I executed the function:
Executing (default): INSERT INTO "UserModel" ("id","username","password","createdAt","updatedAt") VALUES (DEFAULT,$1,$2,$3,$4) RETURNING "id","username","password","createdAt","updatedAt";
Is there anything that I do wrong? Any help will be appreciated, thanks!
Apparently, the problem is within the model. I haven't defined the role in the model init. I solved it by adding the role in model:
UserModel.init({
username: DataTypes.STRING,
password: DataTypes.STRING,
role: DataTypes.STRING
}
Related
I am trying to create data in a user_search table using sequelize.
await UserSearch.create({
searchId: SearchData.search_id,
type: SearchData.type });
and I am getting the error: Error: column "updated_at" of relation "user_search" does not exist but I have not defined updated_at anywhere.
Sequelize Model:
const UserSearch = sequelize.define(
'UserSearch',
{
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER,
},
searchId: {
type: DataTypes.INTEGER,
allowNull: false,
field: 'search_id',
},
type: {
type: DataTypes.STRING,
allowNull: false
},
createdAt: {
type: 'TIMESTAMP',
defaultValue: sequelize.literal('CURRENT_TIMESTAMP'),
allowNull: false,
field: 'created_at'
},
},
{
tableName: 'user_search',
underscored: true,
}
);
DB:
After trying a few things, I have found the answer to my question.
In sequelize, The two columns createdAt and updatedAt are added to your model by the timestamps option which defaults to true.
If you don’t want the columns, you need to set the timestamps option as false when you define your model.
const UserSearch = sequelize.define(
'UserSearch',
{
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER,
},
searchId: {
type: DataTypes.INTEGER,
allowNull: false,
field: 'search_id',
},
type: {
type: DataTypes.STRING,
allowNull: false,
},
createdAt: {
type: 'TIMESTAMP',
defaultValue: sequelize.literal('CURRENT_TIMESTAMP'),
allowNull: false,
field: 'created_at'
},
},
{
tableName: 'user_search',
underscored: true,
timestamps: false
}
);
I have this model:
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Superhero extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate ({ Image, Superpower }) {
// define association here
Superhero.hasMany(Image, { foreignKey: 'superheroId' });
Superhero.hasMany(Superpower, { foreignKey: 'superheroId' });
}
}
Superhero.init(
{
nickname: {
allowNull: false,
type: DataTypes.STRING(128),
validate: { notEmpty: true, notNull: true, len: [1, 128] },
},
realName: {
allowNull: false,
field: 'real_name',
type: DataTypes.STRING(128),
validate: {
notEmpty: true,
notNull: true,
len: [1, 128],
},
},
originDescription: {
allowNull: false,
field: 'origin_description',
type: DataTypes.TEXT,
validate: {
notEmpty: true,
notNull: true,
},
},
superpowers: {
allowNull: false,
type: DataTypes.TEXT,
validate: {
notEmpty: true,
notNull: true,
},
},
catchPhrase: {
allowNull: false,
field: 'catch_phrase',
type: DataTypes.STRING,
validate: {
notEmpty: true,
notNull: true,
len: [1, 255],
},
},
images: {
allowNull: false,
type: DataTypes.TEXT,
validate: {
notNull: true,
notEmpty: true,
},
},
},
{
sequelize,
modelName: 'Superhero',
underscored: true,
tableName: 'superheroes',
}
);
return Superhero;
};
I have such a superpower migration:
'use strict';
module.exports = {
async up (queryInterface, Sequelize) {
await queryInterface.createTable('superpowers', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
superheroId: {
field: 'superhero_id',
allowNull: false,
type: Sequelize.INTEGER,
references: {
model: {
tableName: 'superheroes',
},
key: 'id',
},
onDelete: 'cascade',
onUpdate: 'cascade',
},
superpowerName: {
field: 'superpower_name',
allowNull: false,
type: Sequelize.STRING,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
});
},
async down (queryInterface, Sequelize) {
await queryInterface.dropTable('superpowers');
},
};
When I try to run this command npx sequelize db:migrate, I get an error
Sequelize CLI [Node: 16.14.2, CLI: 6.4.1, ORM: 6.21.0]
Loaded configuration file "src/config/db.json".
Using environment "development".
== 20220704175320-create-superpower: migrating =======
ERROR: relation "superheroes" does not exist
What could be the reason?
I have a hunch that the superpower table is trying to spawn before the superhero table.
Thus, when creating a table with a superpower, an attempt is made to link the "superheroId" field in the superpower table with the "id" field in the superhero table, which does not exist yet.
P.S. If necessary, the file structure looks something like this:
UPD. Migration with superhero:
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Superhero extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate ({ Image, Superpower }) {
// define association here
Superhero.hasMany(Image, { foreignKey: 'superheroId' });
Superhero.hasMany(Superpower, { foreignKey: 'superheroId' });
}
}
Superhero.init(
{
nickname: {
allowNull: false,
type: DataTypes.STRING(128),
validate: { notEmpty: true, notNull: true, len: [1, 128] },
},
realName: {
allowNull: false,
field: 'real_name',
type: DataTypes.STRING(128),
validate: {
notEmpty: true,
notNull: true,
len: [1, 128],
},
},
originDescription: {
allowNull: false,
field: 'origin_description',
type: DataTypes.TEXT,
validate: {
notEmpty: true,
notNull: true,
},
},
superpowers: {
allowNull: false,
type: DataTypes.TEXT,
validate: {
notEmpty: true,
notNull: true,
},
},
catchPhrase: {
allowNull: false,
field: 'catch_phrase',
type: DataTypes.STRING,
validate: {
notEmpty: true,
notNull: true,
len: [1, 255],
},
},
images: {
allowNull: false,
type: DataTypes.TEXT,
validate: {
notNull: true,
notEmpty: true,
},
},
},
{
sequelize,
modelName: 'Superhero',
underscored: true,
tableName: 'superheroes',
}
);
return Superhero;
};
I believe that your syntax is off in the "references" object. The model property should be a string or a static model.
references: {
model: 'superheroes'
key: 'id'
}
Documentation link
I am using sequelize to make query in Redshift.
However Redshift is case-insensitive for Table Column Names, so all table names are lowercase.
And sequelize model isnt case-insensitive. So when I do a query findById, it execute this query:
SELECT "id", "userId", "summonerId", "name", "profileIconId", "summonerLevel", "revisionDate", "createdAt", "updatedAt" FROM "Lol" AS "Lol" WHERE "Lol"."id" = '463d118c-2139-4679-8cdb-d07249bd7777222';
It works if I execute the query inside Redshift, but sequelize just bring me back id and name column names, because only that have the name lowercase in model.
So how I can make sequelize case-insensitive? I tried the field option, but doesnt work.
So my model is:
lol = sequelize.define('Lol', {
id: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
primaryKey: true,
field: 'id'
},
userId: {
type: Sequelize.STRING,
allowNull: false,
field: 'userid'
},
summonerId: {
type: Sequelize.INTEGER,
allowNull: false,
field: 'summonerid'
},
name: {
type: Sequelize.STRING,
allowNull: false,
field: 'name'
},
profileIconId: {
type: Sequelize.INTEGER,
allowNull: false,
field: 'profileiconid'
},
summonerLevel: {
type: Sequelize.INTEGER,
allowNull: false,
field: 'summonerlevel'
},
revisionDate: {
type: Sequelize.BIGINT,
allowNull: false,
field: 'revisiondate'
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
field: 'createdat'
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
field: 'updatedat'
}
}, {
freezeTableName: true,
tableName: 'Lol'
})
Found a way.
Here is now my full setting to make Redshift work with Sequelize:
var Sequelize = require('sequelize');
Sequelize.HSTORE.types.postgres.oids.push('dummy'); // avoid auto-detection and typarray/pg_type error
AWS.config.update({accessKeyId: 'accessKeyId', secretAccessKey: 'secretAccessKey', region: "xxxxxx"});
var sequelize = new Sequelize('database', 'username', 'password', {
host: 'hostname',
dialect: 'postgres',
port: '5439',
pool: {
max: 10,
min: 0,
idle: 20000
},
returning: false, // cause sql error
quoteIdentifiers: false, // set case-insensitive
keepDefaultTimezone: true, // avoid SET TIMEZONE
databaseVersion: '8.0.2' // avoid SHOW SERVER_VERSION
});
This is how my models are structured in sails:
myapp
--api
----controllers
----models
-----User.js
------Role.js
User.js
module.exports = {
attributes:{
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
username: {
type: Sequelize.STRING,
},
password: {
type: Sequelize.STRING,
}
},
associations: function() {
User.hasOne(Role, {foreignKey: 'id', as: 'role' });
}
};
Role.js
module.exports = {
attributes:{
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: Sequelize.STRING,
}
}
};
After sails lift, in the postgresql I have users table with id, username, password, createdat and updatedat + roles table with id, name, createdat and updatedat. No foreignKey for Roles in Users table.
How I can fix this?
I'm using sails-hook-sequelize and sails-hook-sequelize-blueprints, can this occur because of them?
Thanks!
Edit:
The correct way was:
module.exports = {
attributes:{
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
username: {
type: Sequelize.STRING,
},
password: {
type: Sequelize.STRING,
}
},
associations: function() {
User.hasOne(Role, {
as : 'role',
foreignKey: {
name: 'roleId',
allowNull: false
}
});
}
};
The createdAt and updatedAt columns are added by default unless you set the timestamps option to false. See the docs.
To add foreign key constraints, you need to define associations for the Roles model.
New beginner of MongoDB here, I'm using sails.js(based on expressjs)/waterline(ORM)/MongoDB for this project. I have 2 collections, message and user. In any documents in message, there's this field called author that stores a reference/objectId of a user model:
module.exports = {
autoCreatedAt: true,
autoUpdatedAt: true,
schema: true,
tableName: 'message',
attributes: {
from: {
model: 'user',
required: true
},
to: {
model: 'user',
required: true
},
content: {
type: 'string',
maxLength: 288,
required: true
}
}
};
My user collection goes like this:
module.exports = {
autoCreatedAt: true,
autoUpdatedAt: true,
schema: true,
tableName: 'user',
attributes: {
email: {
type: 'string',
email: true,
unique: true,
required: true
},
name: {
type: 'string',
maxLength: 30
},
username: {
type: 'string',
unique: true,
required: true,
maxLength: 80
},
role: {
type: 'string',
required: true
},
......
},
};
Now I want to do a search query to all messages, given a search keyword, I want to show the paginated results of messages which the author's username and content of the message contains the keyword, how can I achieve that?
By the way, I know I can simply store username instead of user reference id in message documents, but says from Mongodb docs, objectId gives way better performance than string so...