Reputation: 2918
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.
Upvotes: 23
Views: 20360
Reputation: 20900
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!
It works in them all the same
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
public static getTableName(): string | {
tableName: string;
schema: string;
delimiter: string;
};
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)
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!
All was tested in:
And for instances! instance.constructor.tableName
is what works !
And it works the same in all of them!
In V6: I tried against boht class User extends Model
and sequelize.define()
! Both works the same!
I tested against different targets:
=> All works the same! And the above is valid for all!
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"
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:
Master is the latest version! (v6 now)
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!
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/dialects/abstract/query-generator.js#L50
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
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)!
Upvotes: 12
Reputation: 2374
Sequelize V6
Just leaving this here incase someone needs it.
Accessing model name: model.name
.
Accessing model table name: model.tableName
.
Note: model
as used above is an instance of sequelize model.
Upvotes: 0
Reputation: 1658
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
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.
Upvotes: 47
Reputation: 1172
For the table name
user.constructor.getTableName()
works great. For the type(the name you give as first param to .define()) you can:
user._modelOptions.name.plural
user._modelOptions.name.singular
Upvotes: 3
Reputation: 7401
Table name: user.Model.getTableName()
or user.Model.tableName
Model name: user.Model.name
Upvotes: 21