Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with calling sequelize.sync() first?

I'm a bit new to developing in nodejs, so this is probably a simple problem. I'm building a typical webapp based on express + sequelize. I'm using sqlite in-memory since I'm just prototyping at the moment. I understand if I were to use a persistent sqlite file, this may not be a problem, but that's not my goal at the moment. Consider the following:

var User = sequelize.define("User", {
    "username": DataTypes.STRING,
    // etc, etc, etc
});

sequelize.sync();

User.build({
    "username": "mykospark"
});

At first, I got an error on User.build() about the Users table not existing yet. I realized that sequelize.sync() was being called async, and the insert was happening before the table was created. I then re-arranged my code so that the User.build() call was inside of sequelize.sync().complete() which fixes the problem, but I'm not sure how to apply this to the rest of my project.

My project uses models in a bunch of different places. It is my understanding that I just want to call sequelize.sync() once after my models are defined, then they can be used freely. I could probably find some way to block the entire nodejs app until sequelize.sync() finishes, but that doesn't seem like good form. I suppose I could wrap every single model operation into a sequelize.sync().complete() call, but that doesn't seem right either.

So how do people usually deal with this?

like image 964
mykospark Avatar asked Jun 26 '14 00:06

mykospark


People also ask

How do I use Sync in Sequelize?

A model can be synchronized with the database by calling model.sync(options) , an asynchronous function (that returns a Promise). With this call, Sequelize will automatically perform an SQL query to the database. Note that this changes only the table in the database, not the model in the JavaScript side.

How do you prevent createdAt and updatedAt in Sequelize?

With timestamps: false , the generated model will omit the createdAt and updatedAt attributes. You can also opt to include only the timestamp attribute you need as shown below: const User = sequelize. define( "User", { firstName: Sequelize.

How do I check if a table exists Sequelized?

you can try to call describeTable of QueryInterface (to get QI call getQueryInterface in sequelize) to get information about a table.


1 Answers

Your .sync() call should be called once within your app.js file. However, you might have additional calls if you manage multiple databases in one server. Typically your .sync() call will be in your server file and the var User = sequelize.define("ModelName"... will be in your models/modelName.js file. Sequelize suggests this type of guidance to "create a maintainable application where the database logic is collected in the models folder". This will help you as your development grows. Later in the answer, I'll provide an easy step to follow for initializing the file structure.

So for your case, you would have app.js, models/index.js and models/users.js. Where app.js would be your server running the .sync() method. In the models folder you will have the required index.js folder where you configure a connection to the database and collect all the model definitions. Finally you have your user.js files where you add your model with class and instance methods. Below is an example of the models/user.js file you might find helpful.

user.js

    module.exports = function(sequelize, DataTypes) {                                                    
    return sequelize.define('User', {                                                             
        username: DataTypes.STRING,                                                                  
    },{                                                                                              
        classMethods: {                                                                              
            doSomething: function(successcb, errcb, request) {}                                             
       },                                                                                           
       instanceMethods: {                                                                           
           someThingElse: function(successcb, errcb, request) {}                                              

       }                                                                                            
     });                                                                                              
   };

models/index.js --> See here

EDIT 03/14/17

Now the best option to setup your node app with sequelize is to use sequelize-cli. This is sequelize migrations and has very useful functionality in development and production environments. For the scope of this question and revision to the answer, the best approach is the following:

npm install sequelize-cli

Use npm install sequelize-cli -g if you want it installed globally.

Then initialize sequelize migrations:

sequelize init

It should install the following folders and files structure in the folder you initiated the command:

config:
   -config.json
models:
   -index.js
seeders:
migrations:

If you want to create a model you can run the following command and it will auto generate the file structure for you. Here is an example

sequelize model:create --name User --attributes "user:string email:string"

Next you should be able to see the new model page in models/page.js.

 config:
   -config.json
models:
   -index.js
   -user.js
   -page.js
seeders:
migrations:

You'll need to then go into you models/index.js and define your new model for your database to access the correct path for that model. Here is an example:

models/index.js

var sq = new Sequelize(dbname, user, password, config);

db = {
    Sequelize: Sequelize,
    sequelize: sq,
    page: sq.import(__dirname + '/page.js'),
    user: sq.import(__dirname + '/user.js')
}
module.exports = db;

If you need to make changes to the model you can go into the migrations folder and add methods. Follow the sequelize migration docs here. Now, about the app.js server. Before you run your server you need to initialize your databases. I use the following script to initialize the database before running the server to setup a postgres db:

postgresInit.sh

[...]
`sudo -u postgres createdb -U postgres -O $PG_USER $PG_DB. `

If you prefer a javascript solution, there is an SO solution here

app.js

[...]
console.log('this will sync your table to your database')
console.log('and the console should read out Executing (default): CREATE TABLE IF NOT EXISTS "TABLE NAME"....')
db.sequelize.sync(function(err){});
like image 93
Val Avatar answered Oct 07 '22 01:10

Val