Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I print out the table name of a sequelize instance?

I would like to print out the table name of an instance that I query with sequelize:

models.User.findById(id).then(user => {
    console.log('instance type is, ', user.getTableName || user.getType)) // => instance type is, users
}

Is there any way to print out the table name of an instance? Is there any way to print out the model name of an instance? I've searched the docs and cannot find the API for the above.

like image 400
robskrob Avatar asked Feb 10 '17 18:02

robskrob


People also ask

How do you find the table name in Sequelize model?

Get the table name of the model, taking schema into account. The method will return The name as a string if the model has no schema, or an object with tableName, schema and delimiter properties. Have schema => return { tableName, schema, delimter } object.

How do I get a Sequelized instance?

There are two ways you can define instance methods with Sequelize: Adding the function to the prototype object. Adding the function to the model created using ES6 class.

What is Sequelize model name?

A model is an abstraction that represents a table in your database. In Sequelize, it is a class that extends Model. The model tells Sequelize several things about the entity it represents, such as the name of the table in the database and which columns it has (and their data types). A model in Sequelize has a name.


3 Answers

piotrbienias' answer is for v3, in v4 you do:

user.constructor.getTableName() or user.constructor.tableName for table name and user.constructor.name for the Model name

ref: Breaking Changes in V4

Took me a while to figure that out so though't I'd post it here in case somebody else comes looking for this answer.

like image 90
mvilrokx Avatar answered Oct 13 '22 02:10

mvilrokx


Table name: user.Model.getTableName() or user.Model.tableName

Model name: user.Model.name

like image 40
piotrbienias Avatar answered Oct 13 '22 03:10

piotrbienias


Note: the short answer is in the first part! You can skim down more to see more details! And interseting elements! And the tests i made! To clear all! You can skim and check the big titles!

From v4 to v6

It works in them all the same

Using the Model class

If we take the Model for example as User!

User.name // => Model name => `User` (you don't need that!
         //     unless you are doing something dynamic!)

User.tableName // => Users
User.getTableName()
             // => Users (no schema)
            // or `"AmASchema"."Users"` (pg), `AmASchema.Users` (MySql)  (schema)
           // or { tableName: 'Users', schema: 'AmASchema', ... } (schema)

We can see in the type definition

enter image description here

enter image description here

  public static getTableName(): string | {
    tableName: string;
    schema: string;
    delimiter: string;
  };

Using Model instance

const user = User.build(...)

user.constructor.name // => User
user.constructor.tableName // => Users

user.constructor.getTableName()
             // => Users (no schema)
            // or `"AmASchema"."Users"` (pg), `AmASchema.Users` (MySql)  (schema)
           // or { tableName: 'Users', schema: 'AmASchema', ... } (schema)

What Doesn't work

instance.name // => undefined
instance.tableName // => undefined

// tested in v4.0, v4.28.10 and v6

I had a wrong assumption and consideration! Where that may be in some versions! instance.name works! And not the constructor version! But no! So far my tests show that it is not! All the above work in all the versions from V4 to V6! And this what doesn't, doesn't in them all!

Know too that I checked in V6, the typescript definition doesn't expose any modeInstance.name or modelInstance.tableName properties!

You can check that in the sequelize model.d.ts type file Line:1527 (Link will take to the line directly! You can CTRL + F and search tableName (within Model class, you'll find only: L1553, L1658, L1679 14 finding, 8 in class Model, different one in comments only!)! [Static property are denoted with Static! Don't confuse them! With instance properties])

instance.Model.name // Error (instance.Model => undefined)
instance.Model.tableName // Error (instance.Model = undefined)

// tested in both v4.0, v4.28.10 and v6

Doesn't work too!

enter image description here

enter image description here

What i tested

All was tested in:

  • v4.0.0
  • v4.28.10
  • v6!

And for instances! instance.constructor.tableName is what works !

And it works the same in all of them!

class User extends Model vs sequelize.define()

In V6: I tried against boht class User extends Model and sequelize.define()! Both works the same!

Typescript and transpilation

I tested against different targets:

  • ES5 (only sequelize.define()! ES5 transpilation doesn't support full ES6 classes (check the why section at the end of the Stackoverflow answer here to know the why))
  • ES6
  • ES2021

=> All works the same! And the above is valid for all!

Log of my results

V6 (Target ES2021, ES6, ES5)

--------------- Testing Models Classes -----------------------


Static access using getTableName() (without Schema) :

Course.getTableName(): Courses


Static access using getTableName() (with Schema) :

User.getTableName(): "AmASchema"."Users"

And ::::

Course.name: Course
Course.tableName: Courses
User.name: User
User.tableName: Users

----

---------------------- Testing Models instances ----------------

Testing using  Class Extends Model definition :::: 

Instance access using instance.name and instance.tableName
course.name: undefined
course.tableName: undefined

Instance access using instance.constructor.name and instance.constructor.tableName and getTableName()

course.constructor.name: Course
course.constructor.tableName: Courses
course.constructor.getTableName(): Courses

Testing using  sequelize.define() definition :::: 

Instance access using instance.name and instance.tableName
user.name: undefined
user.tableName: undefined

Instance access using instance.constructor.name and instance.constructor.tableName and getTableName()

user.constructor.name: User
user.constructor.tableName: Users
user.constructor.getTableName(): "AmASchema"."Users"

V4 (The same)

---------------------- Testing Models Classes ----------------

Static access using getTableName() (without Schema) :

Course.getTableName(): Courses


Static access using getTableName() (with Schema) :

User.getTableName(): "AmASchema"."Users"

And ::::

Course.name: Course
Course.tableName: Courses
User.name: User
User.tableName: Users

----

--------------- Testing Models instances -----------------------

Testing using  sequelize.define() definition :::: 

Instance access using instance.name and instance.tableName

user.name: undefined
user.tableName: undefined

Instance access using instance.constructor.name and instance.constructor.tableName and getTableName()

user.constructor.name: User
user.constructor.tableName: Users
user.constructor.getTableName(): "AmASchema"."Users"

Repo to Check and test for yourself

I shared the test repo publicly! If you like to test quickly! On your machine! You can check the test repo bellow:

https://github.com/MohamedLamineAllal/sequelize-name-and-tableName-test

There is two branches:

  • sequelize/v4
  • sequelize/v6

Master is the latest version! (v6 now)

Detail about Using model Class getTableName()

https://sequelize.org/master/class/lib/model.js~Model.html#static-method-getTableName

public static getTableName(): string | object

Get the table name of the model, taking schema into account. The method will return The name as a string if the model has no schema, or an object with tableName, schema and delimiter properties.

Doesn't have schema => return tableName string

Have schema => return { tableName, schema, delimter } object.

Depending on that we can access in one of the way:

// model has no schema
const tableName = Course.getTableName();

// or

// model has schema
const tableName = Course.getTableName().tableName;

That's statically from the model class directly.

The doc say so! But my tests returned a string even with a schema!

We can see too a mention in the code source type file L1658!

enter image description here

Note: I tried and setup a schema! But the result came as a string!

`"AmASchema"."Users"`

You can check that in the shared logs above!

If any one know what type of schema that may trigger the object return format! Let me know so i add it in the answer!

Note the definition of getTablename():

lib/model.js#L1440

enter image description here

lib/dialects/abstract/query-generator.js#L50

enter image description here

getTableName() vs tableName

Model.getTableName() // No schema: return =>  `Users`
                   // Schema:
                  // return => `"MySchema"."Users"` (Postgres),
                 // `MySchema.Users` (Mysql)
               // Or { tableName: 'Users', schema: 'MySchema', ... }

instance.constructor.getTableName() // same as above

=> will return the schema if there is along with the table name!

While

Model.tableName // return => `Users`
// or
user.constructor.tableName // return => `Users`

=> Will return only the table name

Extra: Note about automatic table naming

By default, when the table name is not given, Sequelize automatically pluralizes the model name and uses that as the table name. This pluralization is done under the hood by a library called inflection, so that irregular plurals (such as Person -> People) are computed correctly.
Of course, this behavior is easily configurable.

User -> Users
Class -> Classes
Person -> People
Child -> Children
Course -> Courses

https://sequelize.org/master/manual/model-basics.html

You can also inforce using the same name as the module (reference)!

like image 27
Mohamed Allal Avatar answered Oct 13 '22 01:10

Mohamed Allal