Sequelize altering all table fields to snake case - node.js

im trying to make a migration to alter all existing table fields to snake case, and future ones to be already written that way.
Up to now i've been doing this with
myTableField = {type: datatype.stmh, field: 'my_table_field'}
thing is i wanna stop doing this and for further upcoming fields i just need them to be set up directly with snake case.
Is there any way of doing this ? or i have to manually run an alter field for each?

Its possible to not rename every field to underscored in the model definition, via the underscored model option.
options.underscored - Converts all camelCased columns to underscored if true
options.underscoredAll - Converts camelCased model names to underscored table names if true
ex:
const User = sequelize.define('User', {
firstname: Sequelize.STRING,
lastname: Sequelize.STRING
},{
underscored:true})
Also on the CLI, we have the option to generate migrations with snakecase
>> sequelize model:generate --name User --attributes firstName:string,lastName:string --underscored
where
--underscored Use snake case for the timestamp's attribute names
But it only does it for the timestamp fields on the migration defs.

Related

Indexing with Mongoose

I was reading the mongoose docs about indexing and want to find out whether there is a difference between field level indexing and schema level indexing. They mention that "defining indexes at the schema level is necessary when creating compound indexes." Are there any other reasons why I might choose one over the other or it is just a preference?
const animalSchema = new Schema({
name: String,
type: String,
tags: { type: [String], index: true } // field level
});
animalSchema.index({ name: 1, type: -1 }); // schema level
When developing your indexing strategy you should have a deep understanding of your application’s queries. Before you build indexes, map out the types of queries you will run so that you can build indexes that reference those fields.
for example you have a query just find based on one field like name so you can indexing name in field level but if you have a query that find based on name and tag so you should indexing name and tag together for this situation you should use indexing in schema level

Difference between postgeSQL table contrains, sequelize options and sequelize validation?

Difference between postgeSQL table contrains, sequelize options and sequelize validation?
For example:
What is the difference between:
title: { type: Sequelize.STRING, allowNull: false},
and
title: { type: Sequelize.STRING, validate: { notNull: true }
and
CREATE TABLE mytable( username TEXT NOT NULL )
In the documentation they say:
// setting allowNull to false will add NOT NULL to the column, which means an error will be
// thrown from the DB when the query is executed if the column is null. If you want to check that a value
// is not null before querying the DB, look at the validations section below.
Why would the error be thrown from the db yet the constrain is in a sequelize model definition? Why not just throw it from sequelize? What is the purpose of the model definition then? Another thing that is confusing me is why we need extra validation from the 'validate option' yet we have constrains in the model as well.
Also what will happen if we put a constrain in the postgreSQL table and not in sequelize model or vice versa?
I suppose that allowNull: false directly translates to NOT NULL constraint when this ORM creates tables.
From https://sequelize.org/v5/manual/models-definition.html
// setting allowNull to false will add NOT NULL to the column, which means an error will be
// thrown from the DB when the query is executed if the column is null.
That is, first and third snippets are equivalent, provided that tables are created with ORM.
Validation in the second snippet happens on the "client" side (that is, when you run your JS code). If you have validation only, but not a constraint in the database then you can set NULL values e.g. by using some other client. If you have a database constraint then no matter what client do you use, you can't set NULL value.

Node/Express Project: Create and Sync a "Join Class/Model" to a Postgres Database

I'm building a Node/Express/Postgres version of an app that I already built in Rails. I'm learning Node, so I figured I'd rebuild something that I know works.
For now, I'm dumping everything in one file (set up my database, defined my models, etc.), just to make sure I have everything set up correctly before I divvy them up into different files.
I set up my postgres database at the very top of the file, like so:
var Sequelize = require('sequelize');
var db = new Sequelize('my_database_name', 'my_username', null, {
host: 'localhost',
dialect: 'postgres',
});
With regard to my models, I have a Politician model:
var Politician = db.define("politician", {
name: {
type: Sequelize.STRING,
},
politicalParty: {
type: Sequelize.STRING
}
});
A Category model:
var Category = db.define("category", {
name: {
type: Sequelize.STRING
},
keywords: {
type: Sequelize.ARRAY(Sequelize.TEXT)
},
});
And a join model of Politician and Category, called "Interest". Because Interest is a join model, it will have a "politicianId" and "categoryId" properties....but will those properties automatically generate in the database? And so, is this how I would define the Interest model, with no properties?
Interest Model:
var Interest = db.define("interest")
Or, will I have to be specific, and create "politicianId" and "categoryId" properties? Like so:
Interest Model:
var Interest = db.define("interest", {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
categoryId: {
type: Sequelize.INTEGER,
foreignKey: true
},
politicianId: {
type: Sequelize.INTEGER,
foreignKey: true
}
});
Also, do I need the "foreignKey: true" bit? Or will it automatically know that those properties are foreign keys? Also, do I need the "id" property? I know models automatically create their own primary key "id"...but again, I've been at this for hours, looking at docs, and trying everything.
I then defined my associations (again, all of this is the same file):
Politician.belongsToMany(Category, {through: "Interest"});
Category.belongsToMany(Politician, {through: "Interest"});
The Node/Sequelize docs seems to suggest that defining those 2 associations above will automatically "create a new model called Interest with the equivalent foreign keys politicianId and categoryId." So, do I even need to define a "Interest" model? Also, do I need the follow associations to describe that Interest belongs to Politician and Category?
Interest.belongsTo(Politician);
Interest.belongsTo(Category);
If I don't write the associations saying that Interest belongs to Politican and Catetory, I don't get the "politicianId" and "categoryId" columns in the Interest table. Just the "id" and createdAt/updatedAt columns.
I then created an instance of Politician, Category, and Interest, to persist everything to the database, to see if everything is there and set up correctly:
Politician Object:
var politician1 = Politician.sync({force: true}).then(function(){
return Politician.create(aPoliticianObjectDefinedInthisFile);
});
This works perfectly. I see this object in the politician table in the database.
Category Object:
var category1 = Category.sync({force: true}).then(function(){
return Category.create(aCategoryObjectDefinedInThisFile);
});
This works perfectly. I see this object in the category table in the database.
Here is what doesn't work. Creating an instance/object of Interest and synching it to the database. My thinking is, if I put integers as values, it will know that "politicianId: 1" means point to the politician object with an id of 1, and the same for "categoryId: 1". But when I write it as I have it below, the Interest table doesn't even show up in the Postgres database at all.
Interest Object:
Interest.sync({force: true}).then(function(){
return Interest.create(
{
politicianId: 1,
categoryId: 1
}
);
});
However, when I create the object of Interest like this, with no properties defined, the Interest table appears in the database, along with the "politicianId" and "categoryId" columns, however, those columns are empty. The object's primary id is in there at 1, and the "createdAt" and "updatedAt" columns have data too. But the foreign key columns are blank.
Interest Object:
Interest.sync({force: true}).then(function()
{
return Interest.create(
{
// No properties defined.
}
);
}
);
Sorry for this long post, lol, but, in all:
Am I creating the "Interest" model correctly?
Am I writing the associations for "Interest" correctly?
Do I even need to write associations for Interest, if I already have associations for its parent classes, Politican and Category defined?
In my Rails app, my associations for Politican and Category are like so:
Politician has_many interests
Politican has_many categories through interests
Category has_many interests
Category has_many politicians through interests
Interest belongs_to politician
Interest belongs_to category
But I use the "belongsToMay" association in Node because I got an error telling me to do so.
Basically, I need to create an instance of Politician, an instance of Category, and an instance of Interest that has "politicianId" and "categoryId" columns that point to those aforementioned instances of those classes.
politicanABC -- id: 1
categoryABC -- id: 1
instanceABC -- id: 1; politicanId: 1 (referring to politicanABC); categoryid: 1 (referring to categoryABC).
My app is set up like that in Rails and works wonderfully.
Help and thank you in advance :-)
You don't have to define the Interest model if you are not going to add any additional fields. Sequelize will internally define the model and add all required fields once you do following:
Politician.belongsToMany(Category, {through: "Interest"});
Category.belongsToMany(Politician, {through: "Interest"});
Sync needs to run on database level and not on tables since Interest model is implicit at this point.
db.sync({force: true});
Sequelize will add relationship build methods on both Politician and Category instances. Category will have methods addPolitician(), addPoliticians([]), setPoliticians([]), getPliticians(). Politician instances will have similar functions to associate categories to them. You can connect these after create option is performed on both objects successfully.
Politician.create({name: 'John Doe', politicalParty: 'Nice Party'})
.then(function(politician) {
Category.create({name: 'Nicers'})
.then(function(category) {
politician.addCategory(category);
});
});
You can also search and associate existing items using helper methods. Alternatively you can associate objects manually by accessing db.models.Interest model and running creates on it.

sequelize for Node.js : ER_NO_SUCH_TABLE

I'm new to sequelize and Node.js.
I coded for test sequelize, but error occured "ER_NO_SUCH_TABLE : Table 'db.node_tests' doesn't exist"
Error is very simple.
However, I want to get data from "node_test" table.
I think sequelize appends 's' character.
There is my source code.
var Sequelize = require('sequelize');
var sequelize = new Sequelize('db', 'user', 'pass');
var nodeTest = sequelize.define('node_test',
{ uid: Sequelize.INTEGER
, val: Sequelize.STRING} );
nodeTest.find({where:{uid:'1'}})
.success(function(tbl){
console.log(tbl);
});
I already create table "node_test", and inserted data using mysql client.
Does I misunderstood usage?
I found the answer my own question.
I appended Sequelize method option following. {define:{freezeTableName:true}}
Then sequelize not appends 's' character after table name.
Though the answer works nicely, I nowadays recommend the use of the tableName option when declaring the model:
sequelize.define('node_test', {
uid: Sequelize.INTEGER,
val: Sequelize.STRING
}, {
tableName: 'node_test'
});
http://docs.sequelizejs.com/manual/tutorial/models-definition.html
Sequelize is using by default the plural of the passed model name. So it will look for the table "node_tests" or "NodeTests". Also it can create the table for you if you want that.
nodeTest.sync().success(function() {
// here comes your find command.
})
Sync will try to create the table if it does not already exist. You can also drop the existing table and create a new one from scratch by using sync({ force: true }). Check the SQL commands on your command line for more details about what is going on.
When you define a model to an existing table, you need to set two options for sequelize to:
find your table name as-is and
not fret about sequelize's default columns updatedAt and createdAt that it expects.
Simply add both options like so:
var nodeTest = sequelize.define('node_test',
{ uid: Sequelize.INTEGER , val: Sequelize.STRING},
{ freezeTableName: true , timestamps: false} //add both options here
);
Note the options parameter:
sequelize.define('name_of_your_table',
{attributes_of_your_table_columns},
{options}
);
Missing either options triggers respective errors when using sequelize methods such as nodeTest.findAll().
> ER_NO_SUCH_TABLE //freezeTableName
> ER_BAD_FIELD_ERROR //timestamps
Alternatively, you can:
create a fresh table through sequelize. It will append "s" to the table name and create two timestamp columns as defaults or
use sequelize-auto, an awesome npm package to generate sequelize models from your existing database programmatically.
Here's the sequelize documentation for option configurations.
In my case, it was due to case. I was having:
sequelize.define('User', {
The correct way is to use lowercase:
sequelize.define('user', {

Sequelize.js how to map a varbinary type from MySQL

I am trying to use Sequelize.js to map all of the columns in my MySQL table.
The mysql table "User" has a Password column as type varbinary(50).
Does Sequelize.js support mapping for a varbinary type? I did not see such an option in the Sequelize docs, is there another way I can map it?
The built-in types in sequelize just maps to strings, so intead of:
User = sequelize.define('user', {
Password: Sequelize.STRING
});
You can write your own string like this:
User = sequelize.define('user', {
Password: 'VARBINARY(50)'
});
This is only necessary if you want sequelize to create your table for you (sequelize.sync()), if you are using pre-created tables it does not matter what you write as the type. The only exception to this is if you are using the Sequelize.BOOLEAN type, which converts 0 and 1 to their boolean value.

Resources