ER_BAD_FIELD_ERROR when using Waterline ORM in Sails.js - javascript

I'm getting the following error when trying to call .create() on a model from a Sails.js controller.
Here is my model, TemperatureReading.js:
module.exports = {
connection: 'mainDatabase',
tableName: 'TemperatureReading',
attributes: {
id: {
columnName: 'id',
type: 'integer',
minLength: 1,
primaryKey: true,
unique: true
},
deviceId: {
columnName: 'deviceId',
type: 'integer',
minLength: 1,
},
temperatureReading: {
columnName: 'temperatureReading',
type: 'string',
max: 150,
required: true
},
dateRecorded: {
columnName: 'dateRecorded',
type: 'string',
},
}
};
routes.js:
module.exports.routes = {
'get /enterSensorReading': 'MainController.getSensorReading'
};
MainController.getSensorReading:
getSensorReading: function (request, response) {
var temperatureReading = request.param('temperatureReading');
var date = new Date();
var dateRecorded = date.getDate() + "/"
+ (date.getMonth()+1) + "/"
+ date.getFullYear() + " "
+ date.getHours() + ":"
+ date.getMinutes() + ":"
+ date.getSeconds();
console.log(temperatureReading);
TemperatureReading.create({temperatureReading: temperatureReading, dateRecorded: dateRecorded}).exec(function(err, createdReading) {
if(err) {
response.send(err);
} else {
console.log('Created reading');
}
});
}
connections.js
module.exports.connections = {
mainDatabase: {
adapter: 'sails-mysql',
host: '127.0.0.1',
port: 3306,
user: 'myUser',
password: 'myPW',
database: 'MAIN'
}
};
And finally, my database structure:
TemperatureReading
------------------
id int(5) PK
deviceId int(5)
temperatureReading varchar(255)
date varchar(255)
Any ideas as to what is going wrong?

The database structure should be something like this:
mysql> describe TemperatureReading;
+--------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| deviceId | int(11) | YES | | NULL | |
| temperatureReading | varchar(255) | YES | | NULL | |
| dateRecorded | varchar(255) | YES | | NULL | |
| createdAt | datetime | YES | | NULL | |
| updatedAt | datetime | YES | | NULL | |
+--------------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
It should be dateRecorded and not just date
If its a new app and you are creating the table from scratch, use add "migrate": "drop" in your model. This will automatically create the table for you. Make sure to remove this line next time you lift the server. If this does not solve the problem, then I don't see any issue with the code. I tested and it worked perfectly on my system. It might be possible that something messed up with your sails-mysql adapter. If fixing your database structure does not solve the problem, try this
npm uninstall sails-mysql
npm cache clear
npm install sails-mysql
Even more rigorous way would be:
rm -Rf node_modules
npm cache clear
npm install
Let me know if this solves the problem you are facing

Related

Sequelize model hasOne get latest record after the where scope

I have 2 tables and using the hasOne to join them.
Table A
| name | value | time |
| ---- | ----- | --------- |
| John | 1 | 2022-01-02|
| John | 2 | 2022-03-04|
User.hasOne(
A,
{
sourceKey: 'name',
foreignKey: 'name',
as: 'name',
scope: {
default: where(col('User.name'), '=', col('data.name')),
},
},
);
Now, is it possible to add an order by time in there? So I always get the latest record?

Prisma: filtering and count in 1-N relationship

model DataProvider {
id Int
name String
applications Application[]
##map("data_providers")
}
model Application {
id Int
name String
data_provider_id Int
running Boolean
data_providers DataProvider
##map("applications")
}
I want to get for each dataProvider how many applications with running = true there are.
DataProvider Application
----------------- -----------------------------------------------
id | name id | name | data_provider_id | running
----------------- -----------------------------------------------
1 | dp1 2 | app2 | 1 | true
-----------------------------------------------
3 | app3 | 1 | false
accordingly to achieve this result
dataProvider = {id: 1, name: 'dp1', _count: {applications: 1}}
I tried with query
this.prisma.dataProvider.findMany({
include: {
_count: {
select: {
applications: true
}
}
},
where: {
applications: {
some: {
running: {
equals: true
}
}
}
},
})
I guess I always get {applications: 2} as a result 2 to some, but I can use only some, every and none. What am I wrong?

Unknown column 'created_at' in 'field list

Here is my customer_schema.js file:
up () {
this.create('customers', (table) => {
table.increments()
table.string('name', 30)
})
}
CustomerSeed.js:
class CustomerSeeder {
async run () {
const customer = await Factory
.model('App/Models/Customer')
.create()
console.log('customer: ')
}
}
The Customer.js model is "empty "
I run the migrations, all is Ok, but can not run the seeds : adonis seed throws this error message:
code: 'ER_BAD_FIELD_ERROR',
errno: 1054,
sqlMessage: "Unknown column 'created_at' in 'field list'",
sqlState: '42S22',
index: 0,
sql:
"insert into `customers` (`created_at`, `name`, `updated_at`) values ('2019-03-04 20:01:17', 'Peter Walsh', '2019-03-04 20:01:17')" }
Why this happens? I did not even declare table.timestamps() in my schema file and :
describe customers;
+-------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(30) | YES | | NULL | |
+-------+------------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)
Edit:
static get createdAtColumn () {
return null;
}
static get updatedAtColumn () {
return null;
}
Add this 2 functions to your model, it should work :)
To add to the previous good answer, when you have lot of models as the application grows, you can automate the above solution instead of writing it as per model:
'use strict'
class NoTimestamp {
register (Model) {
Object.defineProperties(Model, {
createdAtColumn: {
get: () => null,
},
updatedAtColumn: {
get: () => null,
},
})
}
}
module.exports = NoTimestamp
Credit to Romain Lanz who showed me this solution.

How to create a one-to-one relationship using sequelize and mysql?

I am trying to create a one-to-one relationship between two entities. I am using sequelize as ORM to the database mysql.
My model definitions are the following:
var user = (sequelize, DataTypes) => {
const User = sequelize.define('user', {
name: {type: DataTypes.STRING, allowNull: false, unique: true }
}, {
timestamps: false
});
return User;
};
var product = (sequelize, DataTypes) => {
const Product = sequelize.define('product', {
title: {type: DataTypes.STRING, allowNull: false, unique: true, default: 'Coop Default' }
}, {
timestamps: false
});
return Product;
};
and one-to-one relation is made with the following lines of code
db.product.belongsTo(db.user);
db.user.hasOne(db.product);
But, this does not create a unique foreign key in the table products.
mysql> desc products;
+--------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(255) | NO | UNI | NULL | |
| userId | int(11) | YES | MUL | NULL | |
+--------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
What else should I do in the ORM to ensure userId is unique?
I am able to force the unique constraint on the foreignKey by mentioning it in the model definition, apparently, sequelize is not able to do that from the associations.
var product = (sequelize, DataTypes) => {
const Product = sequelize.define('product', {
title: { type: DataTypes.STRING,
allowNull: false,
unique: true
},
userId: { type: DataTypes.INTEGER,
allowNull: false,
unique: true
}
}, {
timestamps: false
});
return Product;
};

How to access variable outside then promise function?

I have used Sequelize with mysql database in my node js application. I want to fetch the value from the db and passed in to the bash script, consider the following code email is fetched from db and stored it in variable but I couldn't access outside of then function
desc users;
+------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| value | varchar(255) | YES | | NULL | |
| created_at | datetime | NO | | NULL | |
| updated_at | datetime | NO | | NULL | |
+------------------+--------------+------+-----+---------+----------------+
6 rows in set (0.24 sec)
code:
User.findOne({where: {name: 'name'}}).then(function(user) {
var name = user.value
});
User.findOne({where: {name: 'email'}}).then(function(user) {
var email = user.value
});
User.findOne({where: {name: 'age'}}).then(function(user) {
var value = user.value
});
var child = exec('bash user.sh name age email')
How to access variables (name, email, age) outside then function in node js?
var child = exec('bash user.sh email')
User.findOne({where: {name: 'usr1'}}).then(function(user) {
var email = user.email;
console.log(child);
},child);
The database query runs asynchronously, So if you want to use any result from the query, you must write that code inside then.
For example -
User.findOne({where: {name: 'usr1'}})
.then(function(user) {
// Do your stuff here.
var email = user.email;
var child = exec('bash user.sh email');
});
The most intuitive solution would be to use async await
(async () => {
const email = await User.findOne({where: {name: 'usr1'}});
const child = exec('bash user.sh email');
})();

Categories

Resources