I have some weird bug when trying to mock my database.
First, here is my User model (with default timestamp because I didnt add anything to options):
const { Sequelize, Model, DataTypes } = require("sequelize");
const sequelize = require("../db");
const User = sequelize.define("user", {
id: {
type: DataTypes.INTEGER, // or maybe Type STRING?
autoIncrement: true,
primaryKey: true,
allowNull: false,
},
first_name: {
type: DataTypes.STRING,
},
last_name: {
type: DataTypes.STRING,
},
email: {
type: DataTypes.STRING,
unique: true,
allowNull: false
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
number_of_answers: {
type: DataTypes.INTEGER,
defaultValue: 0,
}
});
module.exports = User;
I already have one user that I had inserted by Signup endpoint:
Screenshot from psql - SELECT * FROM users;
Now, I am trying to INSERT INTO users and I made a sql file with Mockaroo. Here is example of one line, and error that I am getting when I try to run this command.
psql error on INSERT INTO command
Does anyone know what is a problem here and how can I insert user in colletion via psql.
If you want to know how my endpoint for signup works, here is my code:
// User Signup
router.post("/signup", async (req, res, next) => {
try {
// Crypting password
const hashedPw = await bcrypt.hash(req.body.password, 12);
const results = await User.create({
first_name: req.body.firstName,
last_name: req.body.lastName,
email: req.body.email,
password: hashedPw,
});
res.status(201).json({
status: "User saved to database",
data: {
results: results,
},
});
} catch (err) {
next(err);
}
});
Okay, I found out that I need to put attributes in between "".. So it would be like this below..
INSERT INTO users ("id", ...,"createdAt" ..) VALUES ("idValue", ...);
Related
I have this already created two tables called User and Profile.
This is how my model for User looks like..
const Sequelize = require("sequelize");
const db = require("../db");
const User = db.define("User", {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: {
type: Sequelize.STRING,
allowNull: true,
},
email: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
validator: {
isEmail: true,
},
},
});
module.exports = User;
and model for Profile looks like..
const Sequelize = require("sequelize");
const User = require("./User");
const db = require("../db");
const Profile = db.define("Profile", {
image: {
type: Sequelize.STRING,
},
description: {
type: Sequelize.TEXT,
},
});
module.exports = Profile;
Now I want to define a one-to-one relationship between User and Profile such that user will recieve a profileId column.
so i am defining it like this
Profile.hasOne(User, {
foreignKey: {
allowNull: false,
},
});
User.belongsTo(Profile);
Now i am not able to figure out how to write migrations for the newly added foreign key
can anyone help me please..
Thanks.
I got the answer. for someone who is confused like me here is the answer
since the User table already exists, migrations for the foreignkey will look like this
module.exports = {
async up(queryInterface, Sequelize) {
return await queryInterface.addColumn("Users", "ProfileId", {
type: Sequelize.INTEGER,
references: {
model: "Profiles",
key: "id",
},
});
},
async down(queryInterface, Sequelize) {
return await queryInterface.removeColumn("Users", "ProfileId", {
type: Sequelize.INTEGER,
references: {
model: "Profiles",
key: "id",
},
});
},
};
the Users in addColumn and removeColumn is the name of the table in which foreignkey was added.
the ProfileId is the name for foreignkey which you would have specified in hasOne.
hope this helps..
I'm learning databases, trying to create a user and his two-factor authentication codes. Where one User can have multiple TwoFa
And so, there are 2 tables, User and TwoFa
user.ts
export interface IUser {
id: string;
email: string;
password: string;
twoFa: boolean; // Это флаг, включена ли двухфакторка
}
export interface IUserInstance
extends Model<IUser, Omit<IUser, "id" | "twoFa">>,
IUser,
IDateAt {}
export const User = sequelize.define<IUserInstance>(
"User",
{
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
},
email: {
type: DataTypes.STRING,
unique: true,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
twoFa: {
type: DataTypes.BOOLEAN,
defaultValue: false,
},
}
);
twoFa.ts
interface ITwoFa {
id: string;
ua: string;
}
export interface ITwoFaInstance
extends Model<ITwoFa, Omit<ITwoFa, "id">>,
ITwoFa {}
export const TwoFa = sequelize.define<ITwoFaInstance>(
"TwoFa",
{
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
},
ua: {
type: DataTypes.STRING,
allowNull: false,
}
}
);
Also a file with associations
User.hasMany(TwoFa, {
as: "twoFaCodes",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
TwoFa.belongsTo(User);
await User.sync({ alter: isDev });
await TwoFa.sync({ alter: isDev });
Below is a test script for creating User and TwoFa
const user = awaitUser.create({
login: "someLogin",
email: "someemail#gmail.com",
password: await argon2.hash("sfdsfs"),
});
const twoFaCode = await TwoFa.create(
{
ua: "dsfjdskfsd",
// eslint-disable-next-line #typescript-eslint/ban-ts-comment
// #ts-ignore
User: user // тут ругается тайпскрипт
},
{
include: [User],
},
);
В итоге получаю ошибку
ValidationErrorItem {
message: 'id must be unique',
type: 'unique violation',
path: 'id',
value: '14218bdb-5fef-4777-bdfd-094551d09ec5',
origin: 'DB',
instance: [User],
validatorKey: 'not_unique',
validatorName: null,
validatorArgs: []
}
Actually I have 2 questions now:
What did I do wrong in associations?
How to create the correct type to create TwoFa so that there is no typescript error and the key is not User but user
Thanks!
UPD
if i add in associations foreignKey: "userId", and when creating TwoFa userId: user.id, then everything will work.
Now the question is, why didn’t it work with include?
You're trying to create a user associated with a new TwoFa instance that has the same primary key value.
If you indicate include in create that means you want to create a user along with a TwoFa record and that's not what you want to get.
If you just want to create a TwoFa record and associate it with an existing user then just indicate UserId without include option:
const twoFaCode = await TwoFa.create(
{
ua: "dsfjdskfsd",
UserId: user.id
}
);
By default you will have a foreign key field name as ModelName+Id (UserId) if you don't indicate foreginKey option explicitly in associations
I need a basic email verification after a user signs up.
my pseudo code for this is something like
1.user signs up
2.his data is stored in database.
3.a token is generated using crypto.
4.token is then send to email id provided.
5.user clicks the link a account is verified.
meanwhile a separate sequelize schema is created that stores the email id and the token.
now my problem is how to implement this in my project
passport.use('local-signup', new LocalStrategy(
{
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true // allows us to pass back the entire request to the callback
},
function (req, email, password, done) {
var generateHash = function (password) {
return bCrypt.hashSync(password, bCrypt.genSaltSync(8), null);
};
User.findOne({
where: {
email: email.toLowerCase()
}
}).then(function (user) {
if (user) {
return done(null, false, {
message: 'That email is already taken'
});
}
else {
var userPassword = generateHash(password);
var data =
{
email: email.toLowerCase(),
password: userPassword,
firstname: req.body.firstname,
lastname: req.body.lastname,
mobileno: req.body.mobileno,
//verified_email: false,
//verified_mob: false
};
User.create(data).then(function (newUser, created) {
if (!newUser) {
return done(null, false);
}
if (newUser) {
return done(null, newUser);
}
});
}
});
}
));
i am new to nodejs but with all my understanding i guess things need to be impemented in
if (newUser) {
return done(null, newUser);
}
any guidance is appreciated.
my user schema..
module.exports = function (sequelize, Sequelize) {
var User = sequelize.define('user', {
id: {
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
firstname: {
type: Sequelize.STRING,
notEmpty: true
},
lastname: {
type: Sequelize.STRING,
notEmpty: true
},
//username: { type: Sequelize.STRING },
//about: { type: Sequelize.TEXT },
mobileno: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING,
validate: { isEmail: true }
},
password: {
type: Sequelize.STRING,
allowNull: false
},
last_login: {
type: Sequelize.DATE
},
verified_email: {
type: Sequelize.BOOLEAN,
defaultValue: false,
},
verified_mob: {
type: Sequelize.BOOLEAN,
defaultValue: false,
}
//status: { type: Sequelize.ENUM('active', 'inactive'), defaultValue: 'active' }
});
return User;
}
At any circumstances do not share your token with any of your users. User ID's can easily be extracted by tokens and this can be harmful.
Instead, try this approach;
I assume your user model is something like this at your database
{
name: String,
auth: {
password: String //This will be bcrypted.
email: {
address: String,
verified: String || Boolean,
}
}
}
As you can see, verified field holds a String field or Boolean field.
At the moment you create user, (model.create({...}) sequence) preset the value of verified to sha256 of current time (you can use sha256(moment().format())) and save user.
At mail, send user a link like, yoursite.com/verify?code=[code] and then,
Create a route for user/verify?code=[code] in controller. Get user get the user holds code in verified field and change it to 'true'
You are done.
I'm trying to export data from a html form using sequelize and getting the following error: Cannot read property 'create' of undefined. I'm able to output the data in an object from the form just fine.
routes.js
var db = require("../models");
module.exports = function(app) {
app.post("/api/orders", function(req,res) {
console.log(req.body);
db.orders.create({
date: req.body.date,
billingAddress: req.body.billingAddress,
city: req.body.city,
state: req.body.state,
email: req.body.email,
cupcakeType: req.body.cupcakeType,
quantity: req.body.quantity,
specialInstructions: req.body.specialInstructions,
totalPrice: req.body.totalPrice,
card: req.body.card,
cardNumber: req.body.cardNumber,
cvc: req.body.cvc,
CustomerID: req.body.CustomerID
})
.then(function(dbOrders){
console.log(dbOrders);
res.json(dbOrders);
});
});
orders.js
module.exports = function(sequelize, DataTypes) {
var Orders = sequelize.define("Orders", {
date: {
type: DataTypes.DATEONLY,
allowNull: false
},
billingAddress: {
type: DataTypes.STRING,
allowNull: false,
},
city: {
type: DataTypes.STRING,
allowNull: false,
},
state: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
// validate: {
// isEmail: true
// }
},
Expect to create post to db named 'cupcakes', and table named 'orders'
Take a look at your orders.js file. It looks like you declared this variable
var Orders = sequelize.define("Orders", {...
And you are trying to access db.orders
Looks like you should try accessing db.Orders instead.
I have used sequelize a lot. Their models all start with a Capital letter. You may be able to configure it otherwise, but this is the default behavior.
If you are still having issues, try doing a console.log on db and see what you get.
console.log(db)
Just try this
var db = require("../models");
module.exports = function(app) {
app.post("/api/orders", function(req,res) {
console.log(req.body);
db.Orders.create({
date: req.body.date,
billingAddress: req.body.billingAddress,
city: req.body.city,
state: req.body.state,
email: req.body.email,
cupcakeType: req.body.cupcakeType,
quantity: req.body.quantity,
specialInstructions: req.body.specialInstructions,
totalPrice: req.body.totalPrice,
card: req.body.card,
cardNumber: req.body.cardNumber,
cvc: req.body.cvc,
CustomerID: req.body.CustomerID
})
.then(function(dbOrders){
console.log(dbOrders);
res.json(dbOrders);
});
});
I'm trying to build a simple Node/Express app with Sequelize, but when I try to create a new record in my relational database, I am getting the error Unhandled rejection SequelizeDatabaseError: SQLITE_ERROR: no such table: main.User. Basically, I create a user in the Users table and then try to create a related address in the Addresses table - the user is successfully created but it fails with this error when creating the address... where is it getting the main prefix from in the table name? (full error readout below)...
First off, here's a rundown of my program...
My Sequelize version is Sequelize [Node: 6.8.1, CLI: 2.4.0, ORM: 3.29.0], and I used the Sequelize CLI command sequelize init to set up this portion of my project.
I am using SQLite3 for local development, and in config/config.json I have the development db defined as
"development": {
"storage": "dev.sqlite",
"dialect": "sqlite"
}
My user migration:
'use strict';
module.exports = {
up: function(queryInterface, Sequelize) {
return queryInterface.createTable('Users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
first_name: {
type: Sequelize.STRING
},
last_name: {
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: function(queryInterface, Sequelize) {
return queryInterface.dropTable('Users');
}
};
and the address migration (abbreviated):
module.exports = {
up: function(queryInterface, Sequelize) {
return queryInterface.createTable('Addresses', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
address_line_one: {
type: Sequelize.STRING
},
UserId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: "User",
key: "id"
}
}
})
}
The user model:
'use strict';
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define('User', {
first_name: DataTypes.STRING,
last_name: DataTypes.STRING
}, {
classMethods: {
associate: function(models) {
models.User.hasOne(models.Address);
}
}
});
return User;
};
and the address model:
'use strict';
module.exports = function(sequelize, DataTypes) {
var Address = sequelize.define('Address', {
address_line_one: DataTypes.STRING,
UserId: DataTypes.INTEGER
}, {
classMethods: {
associate: function(models) {
models.Address.hasOne(models.Geometry);
models.Address.belongsTo(models.User, {
onDelete: "CASCADE",
foreignKey: {
allowNull: false
}
});
}
}
});
return Address;
};
finally, my route index.js:
router.post('/createUser', function(req, res){
var firstName = req.body.first_name;
var lastName = req.body.last_name;
var addressLineOne = req.body.address_line_one;
models.User.create({
'first_name': newUser.firstName,
'last_name': newUser.lastName
}).then(function(user){
return user.createAddress({
'address_line_one': newUser.addressLineOne
})
})
So when I try to post to /createUser, the User will successfully be created and the console will say that a new Address has been created (INSERT INTO 'Addresses'...), but the address is NOT created and the following error is logged:
Unhandled rejection SequelizeDatabaseError: SQLITE_ERROR: no such table: main.User
at Query.formatError (/Users/darrenklein/Desktop/Darren/NYCDA/WDI/projects/world_table/wt_test_app_1/node_modules/sequelize/lib/dialects/sqlite/query.js:348:14)
at afterExecute (/Users/darrenklein/Desktop/Darren/NYCDA/WDI/projects/world_table/wt_test_app_1/node_modules/sequelize/lib/dialects/sqlite/query.js:112:29)
at Statement.errBack (/Users/darrenklein/Desktop/Darren/NYCDA/WDI/projects/world_table/wt_test_app_1/node_modules/sqlite3/lib/sqlite3.js:16:21)
I've done this sort of thing with Sequelize once before a few months ago and it was successful, I cannot for the life of me figure out what I'm missing here. Why is the app looking for main.User, and how can I get it to look for the correct table? Thank you!
Aha! A small error has derailed my entire operation. In the migration files, references.model must be pluralized!
references: {
model: "Users",
key: "id"
}
Boom.