Can't connect to the local MySQL in Sails v1.0 - mysql

I'm new to Sails and currently working on connection between Sails project and MySQL. I found that the 'Client Connection' on MySQL Workbench doesn't show any connection after my sails lift and I can't get any data from MySQL also.
[config/datastores.js]
module.exports.datastores = {
default: {
adapter: require('sails-mysql'),
url: 'mysql://root:pw#localhost:3306/database',
}
};
[api/model]
module.exports = {
attributes: {
'username': {
type: 'string',
},
'email': {
type: 'string',
},
'password': {
type: 'string',
},
'create_time': {
type: 'string',
},
},
};
[api/devController]
module.exports = {
index: function(req,res){
model.find().exec(function(err,info){
return res.json(info);
});
},
};
After sails lift, the json return empty.Is that something missing or wrong?

Related

Running Sql migrations throws syntax error

I have created my first migration using sequelize-cli, now when I enter npx sequelize-cli db:migrate to run migration and create table in DB, I get error
I look into documentation could not find how and what should go into migration file.
Error
ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NUMBER, `otp` INTEGER, `otp_expiration_date` DATETIME, `createdAt` DATETIME NOT ' at line 1
My migration File
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('Users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
name: {
type: Sequelize.STRING
},
phone_number: {
type: Sequelize.NUMBER
},
otp: {
type: Sequelize.INTEGER(4)
},
otp_expiration_date: {
type: Sequelize.DATE
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
})
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('Users');
}
};
My User Model:
const moment = require('moment');
'use strict';
module.exports = (sequelize, DataTypes) => {
class User 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(models) {
// define association here
}
};
User.init({
name: {
type: DataTypes.STRING,
allowNull: false
},
phone_number: {
type: DataTypes.NUMBER
},
otp: {
type: DataTypes.INTEGER(4)
},
otp_expiration_date: {
type: DataTypes.DATE,
set(value) {
// convert regular Date to moment Date
value = moment(value).add(5, 'minutes');
this.setDataValue('otp_expiration_date', value);
}
},
is_otp_expired: {
type: DataTypes.VIRTUAL,
get() {
// otp_expiration_date < current date
return this.getDataValue(otp_expiration_date).isAfter(moment()) ? true : false
}
}
}, {
sequelize,
modelName: 'User',
});
return User;
};
I have tried
changing datatypes
moving getters into migration
removing createdAt
[SOLVED]
Problem was with DataType of phone_number , there is no Sequelize.NUMBER type per Sequelize docs
I confused Sequelize DataTypes with MySql DataTypes
phone_number: {
type: DataTypes.NUMBER <---- bug
}
Solution
phone_number: {
type: DataTypes.INTEGER <---- solution
}

Unable to add sails-mysql as non-default datastore

I got stuck for days now, trying to add mysql to my sails project as a non default datastore. If anybody knows a solution. Please
It seems like the additional datastore inside config/datastores.js is not being registered, or the error that is showing is not correct.
"sails": "^1.4.0",
"sails-mysql": "^1.0.1"
I keep getting this error:
error: A hook (orm) failed to load! error: Could not tear down the
ORM hook. Error details: Error: Invalid data store identity. No data
store exist with that identity.
config/datastores.js
module.exports.datastores = {
default: {
adapter: 'sails-disk',
},
mysqlDB: {
adapter: 'sails-mysql',
url: `mysql://${process.env.TC_DB_USERNAME}:${process.env.TC_DB_PASSWORD}#${process.env.TC_DB_HOST}:3306/Auth`,
},
};
api/models/Account.js
module.exports = {
datastore: 'mysqlDB',
schema: false,
};
As a workaround, I am using standard 'mysql' package to connect inside a helper. This works perfectly fine, but is resource heavy and I would love to get standard sails methods (Account.sendNativeQuery()) for the model to work.
If I can't get that to work, maybe someone can tell me how to make this connection global, so I only have to connect once and not on every helper call?
helpers/new-account.js
var mysql = require('mysql');
var connection = mysql.createConnection({
host: process.env.TC_DB_HOST,
user: process.env.TC_DB_USERNAME,
password: process.env.TC_DB_PASSWORD,
database: 'Auth',
});
connection.connect();
module.exports = {
friendlyName: 'Creates new account',
description: 'returns the id of the new usr or throws error',
inputs: {
username: {
description: 'The new account name.',
type: 'string',
required: true,
minLength: 4,
maxLength: 64,
},
salt: {
required: true,
type: 'ref',
description: 'generated salt.',
},
verifier: {
required: true,
type: 'ref',
description: 'generated verifier.',
},
email: {
required: true,
type: 'string',
isEmail: true,
description: 'Email linked to account.',
},
},
exits: {
success: {
description: 'All done.',
},
},
fn: async function ({ username, salt, verifier, email }, exits) {
connection.query(
'INSERT INTO account SET ?',
{ username, salt, verifier, email },
function (err, result) {
if (err) {
throw new Error(`MYSQL ERROR: ${err}`);
} else {
console.log(`new user with id ${result.insertId} created.`);
exits.success(result.insertId);
}
}
);
connection.end();
},
};
Thank you
Try requiring the sails-mysql package rather than just including the stringified name, for example:
module.exports.datastores = {
default: {
adapter: 'sails-disk',
},
mysqlDB: {
adapter: require('sails-mysql'),
url: `mysql://${process.env.TC_DB_USERNAME}:${process.env.TC_DB_PASSWORD}#${process.env.TC_DB_HOST}:3306/Auth`,
},
};

How to add new attributes to schema after the migration?

currently I am working on a node.js project, and I found a problem while I was building the schema, usually, I use command line provided by http://docs.sequelizejs.com/manual/tutorial/migrations.html to define my schema, which is $ node_modules/.bin/sequelize model:generate --name User --attributes firstName:string,lastName:string,email:string , and after the $ node_modules/.bin/sequelize db:migrate, I can write these attributes into database. However, I am wondering how to add new attribute to schema after the migration, I searched and found this https://github.com/sequelize/cli/issues/133 is discussing this problem, but after I tried the solution and run $ node_modules/.bin/sequelize db:migrate again, it did not write the new attributes to the original schema, I don't understand where's the problem, below is my code, I am trying to add two attributes 'address'& 'height' into the user schema, can you guys give me some advice? Thank you!
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
let migration = [];
migrations.push(queryInterface.addColumn(
'address',
'height',
{
type: Sequelize.STRING,
}
));
return Promise.all(migrations);
return queryInterface.createTable('Users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
firstName: {
type: Sequelize.STRING,
},
lastName: {
type: Sequelize.STRING,
},
email: {
type: Sequelize.STRING,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Users');
}
};
this issue has been solved, you can use below link How to Add, Delete new Columns in Sequelize CLI to solve that issue, also you can check the query part of sequelize to see the documents http://docs.sequelizejs.com/class/lib/query-interface.js~QueryInterface.html, The real answer should be
module.exports = {
up: function (queryInterface, Sequelize) {
return [
queryInterface.addColumn(
'users',
'height',
{
type: Sequelize.STRING,
}
),
queryInterface.addColumn(
'users',
'address',
{
type: Sequelize.STRING,
}
)
];
},
down: function (queryInterface, Sequelize) {
return [
queryInterface.removeColumn('users', 'height'),
queryInterface.removeColumn('users', 'address')
];
}
};
and then you can type
sequelize migration:create --name add-height-and-address-to-user
sequelize db:migrate
to migrate new attributes into your model.

how to store object type field in mysql using sails

I want that my model fields will store in mysql as it is. My user model is like this:
module.exports = {
attributes: {
local: {
email: 'string',
password: 'string'
},
facebook: {
id: 'string',
token: 'string',
email: 'string',
name: 'string'
},
google: {
id: 'string',
token: 'string',
email: 'string',
name: 'string'
}
}
};
But this does not create any field in user model. What should I do for storing these fields in mysql ?
You'll need to save them as JSON objects. Sails will stringify your objects and save the result in your database. It will also take care of the parsing, so you don't have to worry about that. Still it doesn't allow specifying the inner attributes of the objects, but I don't think there's a solution for that.
module.exports = {
attributes: {
local: {
type: 'json'
},
facebook: {
type: 'json'
},
google: {
type: 'json'
}
}
};

Mongoose many to many relation and circular structure to JSON

I am trying to create a classic Articles/Categories association with mongoose.
Everything works fine, but since I am trying to expose the query results as JSON, I get a Converting circular structure to JSON error.
I know the issue is related in cross referencing models, but I don't know how to solve this.
Here are my model schemas.
var ArticleSchema = new Schema({
created: {
type: Date,
default: Date.now
},
title: {
type: String,
default: '',
trim: true
},
content: {
type: String,
default: '',
trim: true
},
user: {
type: Schema.ObjectId,
ref: 'User'
},
categories: [{
type: Schema.ObjectId,
ref: 'Category'
}]
});
ArticleSchema.statics.load = function(id, cb) {
this.findOne({
_id: id
}).populate('user', 'name username').populate('categories', 'title').exec(cb);
};
/**
* Category Schema
*/
var CategorySchema = new Schema({
created: {
type: Date,
default: Date.now
},
title: {
type: String,
default: '',
trim: true
},
user: {
type: Schema.ObjectId,
ref: 'User'
}
},
{
toObject: { virtuals: true },
toJSON: { virtuals: true }
});
/**
* Virtual Schema
*/
var articles = CategorySchema.virtual('articles');
articles.get(function () {
return Article.find({categories : { $eq: this }});
});
Seems to be like you have circular references, this mean that the json you create is calling it self in somere.. Im not sure if this line could be the problem:
articles.get(function () {
return Article.find({categories : { $eq: this }});
});
why dont you try with a hardcore value in $eq ??