Hi all,
I using v4 to defined my model as:
@Options({
sequelize,
tableName: 'V2_category',
timestamps: false
})
@Attributes({
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: DataTypes.STRING,
name_vi: DataTypes.STRING,
code: DataTypes.STRING,
type: DataTypes.STRING,
created_at: DataTypes.DATE,
updated_at: DataTypes.DATE,
})
export class V2Category extends Model {
get fullName() {
return this.name + '-' + this.name_vi;
}
set fullName(fullName) {
const names = fullName.split(' ');
this.name = names.pop();
this.name_vi = names.join(' ');
}
}
and i import in others:
import {V2Category as category} from '../models/V2_category';
my query :
findCategoryById (id) {
return category.findOne({ where: { 'id': id } });
}
When run i got an error:
Unhandled rejection TypeError: Class constructor Model cannot be invoked without 'new'
However, i add { where: { 'id': id }, raw: true }
my code working but i can't use getter function fullName. Could you tell me where my mistake and how to fix it? Thanks
Please post the whole stack trace
I had the same problem
During debugging I found out that the Model constructor returns a class instead of a function
I have a suspicion that the problem arises at the moment of inheritance
In JavaScript, a class is a function.
@felixfbecker nice joke, I'm very familiar with JS
I could not understand why he inherited this error when he inherited
But if you go the old way and use define, the error disappears
static build(values, options) {
if (Array.isArray(values)){
return this.bulkBuild(values, options);
}
return new this(values, options);
}`
I have the same problem.
I think it has something to do with the way babel transpiles the code. After I changed my .babelrc
file to this:
{
"presets": [
["env", {
"targets": {
"node": "current"
}
}]
]
}
it works as expected.
Yes, that is very likely.
@zonorion could you post the transpiled JS of that model?
Intypescript
case, my solution was to change target from es5
to es6
{
"compilerOptions": {
"target": "es6", // <=
// ...
}
}
I'm getting this as well. Just upgraded from 3 to 4.4.2
, and when I change my model definitions to:
const attributes = {/*...*/};
const options = {
sequelize,
};
class User extends Sequelize.Model {
someInstanceMethod() {}
}
User.someStaticMethod = () => {};
User.init(attributes, options);
I started seeing the error anytime Sequelize attempted to create an instance of User
(such as User.findOne()
).
My .babelrc
:
{
"presets": ["es2015", "react", "stage-0"]
}
Switching to this for now:
const User = sequelize.define('User', attributes, options);
User.prototype.someInstanceMethod = function() {}; // function can't be () => {}
User.someClassMethod = () => {};
@juhaelee says:
You just need to use the env preset package instead of es2015
```{
"presets": [
["env", {
"targets": {
"node": "current"
}
}],
"stage-1"
],
"plugins": []
}
Sr, i missed any notifications
I used:
{
"presets": [
"es2015-node6",
"stage-3"
],
"plugins": [
["transform-decorators-legacy"],
[
"transform-runtime",
{
"polyfill": false,
"regenerator": true
}
],
[
"istanbul",
{
"exclude": [
"test/*.js"
]
}
]
]
}
sequelize woking fine!
It turns out that an ES6-class transpiled by babel can't extend a real ES6 class (The Sequelize.Model
ES6-class for example).
So class MyEntity extends Sequelize.Model { ... }
won't work if MyEntity
is transpiled into ES5.
The solution i used, was to use es2015-node5
instead of es2015
. But ONLY on the server, of course, not on the client - i.e. not when transpiling for the browser. So i didn't put this in my .babelrc, but added it to the "build-server" command-line scripts in package.json instead: babel .... --no-babelrc --presets=es2015-node5,stage-0,react
.
have almost the same problem how do i solve it ... looking for a solution
@corneliouzbett
have almost the same problem how do i solve it ... looking for a solution
do you found solution ?
I'm getting this error as well when using some of the example code listed within Express / Sequelize setup. Seems the the offending line of code is within the cli's default generated models/index.js
const model = sequelize['import'](path.join(__dirname, file))
Altered things with babel and so forth, but haven't gotten it working just yet.
Turns out in my case, I had a previously created model in the models folder that was causing things to break:
const Sequelize = require('sequelize')
const db = require('../sequelize')
const Post = db.define('post', {
title: Sequelize.STRING(255),
body: Sequelize.TEXT('long'),
excerpt: Sequelize.STRING(500),
tags: Sequelize.STRING(500),
slug: Sequelize.STRING(255),
thumbnail_path: Sequelize.STRING(255),
hero_path: Sequelize.STRING(255),
updatedAt: Sequelize.DATE
})
module.exports = Post
This was preventing the file from being read correctly by sequelize and causing the error listed in this thread. Advice for others: Make sure all of your code inside of your models folder is valid and from examples.
For those running into this, this is a bug in babel
. I haven't been able to solve it on my end using the suggested solutions likely because I use babel runtime transformations. There is a PR open @babel to resolve this. Hopefully it will be merged soon. https://github.com/babel/babel/pull/8656
Mine got solved via:
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": true
}
}
]
]
}
Im not using a transpiler and i have this error as well
Same issue here and my .babelrc is:
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "current"
}
}
]
]
}
Any other suggestions to solve this?
Just in case it helps someone else: in my case the issue was that I was using --presets @babel/preset-env
with the babel command, so my babel.config.js
file with presets: [['@babel/preset-env', {targets: {node: 'current'}}]]
was being ignored...
For anyone having trouble with this using Jest and Expo (React Native), you may need to add sequelize to to the transformIgnorePatterns
in the jest config.
My
jest.config.js
module.exports = {
preset: "jest-expo",
reporters: [
"default",
[
"./node_modules/jest-html-reporters",
{
filename: "./public/test-report.html",
pageTitle: "BioPointe: Unit Tests",
},
],
],
coverageDirectory: "./public/coverage",
snapshotSerializers: ["./src/BioPointe.serializer.js"],
transformIgnorePatterns: [
"node_modules/(?!((jest-)?" +
// If having issues with complation/runtime in tests regarding language
// features, you may want to add entries to this array for the relevant
// modules.
[
"react-native",
"react-clone-referenced-element",
"expo(nent)?",
"@unimodules/.*",
"jest-expo/.*",
"@expo(nent)?/.*",
"react-navigation",
"@react-navigation/.*",
"sentry-expo",
"sequelize",
"native-base",
"@sentry/.*",
"unimodules-.*",
].join("|") +
"))",
],
};
For anyone who comes to this and the reason was not transpiling. For me it was because I was exporting my models as classes, and the line from the generated models/index.js :
const model = sequelize['import'](path.join(__dirname, file))
was causing the error. Once I changed that line to:
let model = require(path.join(__dirname, file));
It was fixed
Hi guys, I have the same issue with tsc (TypeScript compiler).
{
"compilerOptions": {
"target": "ES6",
"module": "CommonJS",
"moduleResolution": "node",
"lib": ["ES5", "ES6"],
"declaration": true,
"outDir": "./build",
"strict": true,
"esModuleInterop": true,
"allowJs": false,
"allowSyntheticDefaultImports": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"strictPropertyInitialization": false,
"sourceMap": true
},
"include": ["src"],
"exclude": ["node_modules"]
}
{
"sequelize": "^5.21.6",
"ts-node": "^8.10.1",
"typescript": "^3.7.2"
}
import { Model, DataTypes } from 'sequelize';
import sequelize from './';
import { OrderStatus } from '../components/constants';
class Order extends Model {
public id!: number;
public total!: number;
public finalTotal!: number;
public status: OrderStatus;
public start_date: Date;
public end_date: Date;
public created_at: Date;
public updated_at: Date;
}
Order.init({
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4
},
total: {
type: DataTypes.INTEGER,
allowNull: true,
},
finalTotal: {
type: DataTypes.INTEGER,
allowNull: true,
validate: {
len: {
args: [2, 5],
msg: 'Name must be from 2 to 5 characters in length'
},
}
},
status: {
type: DataTypes.ENUM(OrderStatus.InProcess, OrderStatus.Done)
},
}, {
sequelize,
tableName: 'orders',
})
export default Order;
const modelsPath = `${__dirname}/../src/models`;
const models = fs
.readdirSync(modelsPath)
.filter((filename: string) => /model.ts$/.test(filename))
.reduce((total: any, filename: string) => {
const model = sequelize.import(path.join(modelsPath, filename));
total[capitalize(model.name)] = model;
return total;
}, {});
// Sets up the associations for each model.
Object.keys(models).forEach((modelName: string) => {
if ('associate' in models[modelName]) {
models[modelName].associate(models);
}
});
TypeError: Class constructor Order cannot be invoked without 'new'
at Sequelize.import (node_modules/sequelize/lib/sequelize.js:486:38)
at /home/cuongw/Workspace/SaveMoney/service-template/test/utils.ts:18:37
at Array.reduce (<anonymous>)
at Object.exports.prepareModels (test/utils.ts:17:6)
at Object.exports.loadFixtures (test/utils.ts:35:18)
at Context.<anonymous> (test/order.test.ts:16:11)
at processImmediate (internal/timers.js:456:21)
Please tell me a solution. Thank all.
I had the same error with typescript and it was fixed when I updated the tsconfig.json changing the es5 for es6
"compilerOptions": {
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. /
"module": "commonjs", / Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
I had the same error with typescript and it was fixed when I updated the tsconfig.json changing the es5 for es6
"compilerOptions": {
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. _/ "module": "commonjs", /_ Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
Thank for your reply. I used ES6
for target
but it doesn't work.
Hi guys, I have the same issue with tsc (TypeScript compiler).
tscconfig.json
{ "compilerOptions": { "target": "ES6", "module": "CommonJS", "moduleResolution": "node", "lib": ["ES5", "ES6"], "declaration": true, "outDir": "./build", "strict": true, "esModuleInterop": true, "allowJs": false, "allowSyntheticDefaultImports": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "strictPropertyInitialization": false, "sourceMap": true }, "include": ["src"], "exclude": ["node_modules"] }
version
{ "sequelize": "^5.21.6", "ts-node": "^8.10.1", "typescript": "^3.7.2" }
model
import { Model, DataTypes } from 'sequelize'; import sequelize from './'; import { OrderStatus } from '../components/constants'; class Order extends Model { public id!: number; public total!: number; public finalTotal!: number; public status: OrderStatus; public start_date: Date; public end_date: Date; public created_at: Date; public updated_at: Date; } Order.init({ id: { type: DataTypes.UUID, primaryKey: true, defaultValue: DataTypes.UUIDV4 }, total: { type: DataTypes.INTEGER, allowNull: true, }, finalTotal: { type: DataTypes.INTEGER, allowNull: true, validate: { len: { args: [2, 5], msg: 'Name must be from 2 to 5 characters in length' }, } }, status: { type: DataTypes.ENUM(OrderStatus.InProcess, OrderStatus.Done) }, }, { sequelize, tableName: 'orders', }) export default Order;
sequelize.import
const modelsPath = `${__dirname}/../src/models`; const models = fs .readdirSync(modelsPath) .filter((filename: string) => /model.ts$/.test(filename)) .reduce((total: any, filename: string) => { const model = sequelize.import(path.join(modelsPath, filename)); total[capitalize(model.name)] = model; return total; }, {}); // Sets up the associations for each model. Object.keys(models).forEach((modelName: string) => { if ('associate' in models[modelName]) { models[modelName].associate(models); } });
error
TypeError: Class constructor Order cannot be invoked without 'new' at Sequelize.import (node_modules/sequelize/lib/sequelize.js:486:38) at /home/cuongw/Workspace/SaveMoney/service-template/test/utils.ts:18:37 at Array.reduce (<anonymous>) at Object.exports.prepareModels (test/utils.ts:17:6) at Object.exports.loadFixtures (test/utils.ts:35:18) at Context.<anonymous> (test/order.test.ts:16:11) at processImmediate (internal/timers.js:456:21)
Please tell me a solution. Thank all.
require
instead of sequelize.import
. 馃槗In
typescript
case, my solution was to change target fromes5
toes6
{ "compilerOptions": { "target": "es6", // <= // ... } }
Works for me! Thanks
let model = require(path.join(__dirname, file))
I am having the same issue, changed the appropriate line, still no luck.
After much searching I found that this error does sometimes occur when the entity column type cannot be inferred.
These are the only values that can automap:
string | STRING
boolean | BOOLEAN
number | INTEGER
bigint | BIGINT
Date | DATE
Buffer | BLOB
If you are using any other value, for example a UUID you need to set that in the column annotation
@Column({type: DataType.UUIDV4})
Hope that helps anyone else going down this rabbit hole.
Most helpful comment
In
typescript
case, my solution was to change target fromes5
toes6