te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - [NodeJs][Sequelize] ReferenceError: Cannot access 'ModelName' before initialization - Stack Overflo
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - [NodeJs][Sequelize] ReferenceError: Cannot access 'ModelName' before initialization - Stack Overflo

programmeradmin2浏览0评论

Currently I realize an API using Node Js 13 and the ORM Sequelize v5 and all this in ES6 (via "type": "module" in package.json).

In this project there is a problem when I try to use associations.

I have three models which are associated: author.js, authorbook.js and book.js .

author.js:

import Sequelize from 'sequelize';
import AuthorBook from './authorbook.js';
import dotenv from 'dotenv';

dotenv.config();

const sequelize = new Sequelize(
  process.env.DB_DATABASE, process.env.DB_USERNAME, process.env.DB_PASSWORD,{
    host: process.env.DB_HOST,
    dialect: 'mysql'
  }
);

export default class Author extends Sequelize.Model {}
Author.init({
  firstName: {
    firstName: false,
    type: Sequelize.STRING(100)
  },
  lastName: {
    allowNull: false,
    type: Sequelize.STRING(100)
  }
}, { sequelize });

Author.hasMany(AuthorBook, {
  onUpdate: 'CASCADE'
});

book.js:

import Sequelize from 'sequelize';
import AuthorBook from './authorbook.js';
import dotenv from 'dotenv';

dotenv.config();

const sequelize = new Sequelize(
  process.env.DB_DATABASE, process.env.DB_USERNAME, process.env.DB_PASSWORD,{
    host: process.env.DB_HOST,
    dialect: 'mysql'
  }
);

export default class Book extends Sequelize.Model {}
Book.init({
  title: {
    firstName: false,
    type: Sequelize.STRING(100)
  }
}, { sequelize });

Book.hasMany(AuthorBook, {
  onUpdate: 'CASCADE'
});

authorbook.js:

import Sequelize from 'sequelize';
import Author from './author.js';
import Book from './book.js';
import dotenv from 'dotenv';

dotenv.config();

const sequelize = new Sequelize(
  process.env.DB_DATABASE, process.env.DB_USERNAME, process.env.DB_PASSWORD,{
    host: process.env.DB_HOST,
    dialect: 'mysql'
  }
);

export default class AuthorBook extends Sequelize.Model {}
AuthorBook.init({
  authorId: {
    type: Number,
    allowNull: false
  },
  bookId: {
    type: Number,
    allowNull: false
  },
}, { sequelize });

AuthorBook.belongsTo(Author, { foreignKey: 'authorId'});
AuthorBook.belongsTo(Book, { foreignKey: 'bookId'});

Here is the error I get when I run the cmd node src/server.js:

(node:23142) ExperimentalWarning: The ESM module loader is experimental.
file:///Users/alexandre/Documents/project/server/src/db/models/.js:18
Author.hasMany(AuthorBook, {
               ^

ReferenceError: Cannot access 'AuthorBook' before initialization
    at file:///Users/alexandre/Documents/project/server/src/db/models/author.js:38:22
    at ModuleJob.run (internal/modules/esm/module_job.js:110:37)
    at async Loader.import (internal/modules/esm/loader.js:176:24)

Someone can help me ?

Currently I realize an API using Node Js 13 and the ORM Sequelize v5 and all this in ES6 (via "type": "module" in package.json).

In this project there is a problem when I try to use associations.

I have three models which are associated: author.js, authorbook.js and book.js .

author.js:

import Sequelize from 'sequelize';
import AuthorBook from './authorbook.js';
import dotenv from 'dotenv';

dotenv.config();

const sequelize = new Sequelize(
  process.env.DB_DATABASE, process.env.DB_USERNAME, process.env.DB_PASSWORD,{
    host: process.env.DB_HOST,
    dialect: 'mysql'
  }
);

export default class Author extends Sequelize.Model {}
Author.init({
  firstName: {
    firstName: false,
    type: Sequelize.STRING(100)
  },
  lastName: {
    allowNull: false,
    type: Sequelize.STRING(100)
  }
}, { sequelize });

Author.hasMany(AuthorBook, {
  onUpdate: 'CASCADE'
});

book.js:

import Sequelize from 'sequelize';
import AuthorBook from './authorbook.js';
import dotenv from 'dotenv';

dotenv.config();

const sequelize = new Sequelize(
  process.env.DB_DATABASE, process.env.DB_USERNAME, process.env.DB_PASSWORD,{
    host: process.env.DB_HOST,
    dialect: 'mysql'
  }
);

export default class Book extends Sequelize.Model {}
Book.init({
  title: {
    firstName: false,
    type: Sequelize.STRING(100)
  }
}, { sequelize });

Book.hasMany(AuthorBook, {
  onUpdate: 'CASCADE'
});

authorbook.js:

import Sequelize from 'sequelize';
import Author from './author.js';
import Book from './book.js';
import dotenv from 'dotenv';

dotenv.config();

const sequelize = new Sequelize(
  process.env.DB_DATABASE, process.env.DB_USERNAME, process.env.DB_PASSWORD,{
    host: process.env.DB_HOST,
    dialect: 'mysql'
  }
);

export default class AuthorBook extends Sequelize.Model {}
AuthorBook.init({
  authorId: {
    type: Number,
    allowNull: false
  },
  bookId: {
    type: Number,
    allowNull: false
  },
}, { sequelize });

AuthorBook.belongsTo(Author, { foreignKey: 'authorId'});
AuthorBook.belongsTo(Book, { foreignKey: 'bookId'});

Here is the error I get when I run the cmd node src/server.js:

(node:23142) ExperimentalWarning: The ESM module loader is experimental.
file:///Users/alexandre/Documents/project/server/src/db/models/.js:18
Author.hasMany(AuthorBook, {
               ^

ReferenceError: Cannot access 'AuthorBook' before initialization
    at file:///Users/alexandre/Documents/project/server/src/db/models/author.js:38:22
    at ModuleJob.run (internal/modules/esm/module_job.js:110:37)
    at async Loader.import (internal/modules/esm/loader.js:176:24)

Someone can help me ?

Share Improve this question edited Apr 11, 2020 at 21:50 Alexandre FERREIRA asked Apr 11, 2020 at 20:47 Alexandre FERREIRAAlexandre FERREIRA 1051 gold badge2 silver badges8 bronze badges 3
  • 1 move all association definitions in associations.js and import all your models in it. I guess you have a circular reference. – Anatoly Commented Apr 11, 2020 at 20:57
  • The error is because of cyclic dependency, authorBook.js imports author.js and book.js and both of these again import authBook.js – Anshul Sahni Commented Apr 11, 2020 at 22:05
  • Hello, first thank you for your quick answer. Can you show me how to do this ? – Alexandre FERREIRA Commented Apr 11, 2020 at 22:49
Add a ment  | 

1 Answer 1

Reset to default 13

The error means there are circular references between your modules. You should put the models in a module like index.ts and make the associations here. Please pay attention to my file directory structure:

E.g.

./models/book.ts:

import Sequelize from 'sequelize';
import { sequelize } from '../../../db';

export default class Book extends Sequelize.Model {}
Book.init(
  {
    title: {
      allowNull: false,
      type: Sequelize.STRING(100),
    },
  },
  { sequelize, modelName: 'books' },
);

./models/author.ts:

import Sequelize from 'sequelize';
import { sequelize } from '../../../db';

export default class Author extends Sequelize.Model {}
Author.init(
  {
    firstName: {
      allowNull: false,
      type: Sequelize.STRING(100),
    },
    lastName: {
      allowNull: false,
      type: Sequelize.STRING(100),
    },
  },
  { sequelize, modelName: 'authors' },
);

./models/authorbook.ts:

import Sequelize from 'sequelize';
import { sequelize } from '../../../db';

export default class AuthorBook extends Sequelize.Model {}
AuthorBook.init(
  {
    authorId: {
      type: Sequelize.INTEGER,
      allowNull: false,
    },
    bookId: {
      type: Sequelize.INTEGER,
      allowNull: false,
    },
  },
  { sequelize, modelName: 'authorbooks' },
);

./models/index.ts:

import Author from './author';
import Book from './book';
import AuthorBook from './authorbook';

Author.hasMany(AuthorBook, {
  onUpdate: 'CASCADE',
});
Book.hasMany(AuthorBook, {
  onUpdate: 'CASCADE',
});
AuthorBook.belongsTo(Author, { foreignKey: 'authorId' });
AuthorBook.belongsTo(Book, { foreignKey: 'bookId' });

export { Author, Book, AuthorBook };

Now, we can use these models.

index.ts:

import { Author, AuthorBook, Book } from './models';
import { sequelize } from '../../db';
import faker from 'faker';

(async function test() {
  try {
    await sequelize.sync({ force: true });
    // seed
    const author = await Author.create({
      firstName: faker.name.firstName(),
      lastName: faker.name.lastName(),
    });
    const book = await Book.create({
      title: faker.lorem.words(3),
    });
    await AuthorBook.create({ authorId: author.id, bookId: book.id });
  } catch (error) {
    console.log(error);
  } finally {
    await sequelize.close();
  }
})();

The execution results:

Executing (default): DROP TABLE IF EXISTS "authorbooks" CASCADE;
Executing (default): DROP TABLE IF EXISTS "books" CASCADE;
Executing (default): DROP TABLE IF EXISTS "authors" CASCADE;
Executing (default): DROP TABLE IF EXISTS "authors" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "authors" ("id"   SERIAL , "firstName" VARCHAR(100) NOT NULL, "lastName" VARCHAR(100) NOT NULL, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'authors' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): DROP TABLE IF EXISTS "books" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "books" ("id"   SERIAL , "title" VARCHAR(100) NOT NULL, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'books' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): DROP TABLE IF EXISTS "authorbooks" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "authorbooks" ("id"   SERIAL , "authorId" INTEGER NOT NULL REFERENCES "authors" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "bookId" INTEGER NOT NULL REFERENCES "books" ("id") ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'authorbooks' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "authors" ("id","firstName","lastName") VALUES (DEFAULT,$1,$2) RETURNING *;
Executing (default): INSERT INTO "books" ("id","title") VALUES (DEFAULT,$1) RETURNING *;
Executing (default): INSERT INTO "authorbooks" ("id","authorId","bookId") VALUES (DEFAULT,$1,$2) RETURNING *;

check the database:

node-sequelize-examples=# select * from "authors";
 id | firstName | lastName
----+-----------+----------
  1 | Laron     | Deckow
(1 row)

node-sequelize-examples=# select * from "books";
 id |          title
----+-------------------------
  1 | facilis molestias sequi
(1 row)

node-sequelize-examples=# select * from "authorbooks";
 id | authorId | bookId
----+----------+--------
  1 |        1 |      1
(1 row)

Dependencies versions: "sequelize": "^5.21.3", postgres:9.6

source code: https://github./mrdulin/node-sequelize-examples/tree/master/src/examples/stackoverflow/61163520

发布评论

评论列表(0)

  1. 暂无评论