Sequelize 6 从文件中导入模型
Posted
技术标签:
【中文标题】Sequelize 6 从文件中导入模型【英文标题】:Sequelize 6 import models from file 【发布时间】:2020-10-14 19:20:36 【问题描述】:我想知道如何使用 ?
它适用于“续集”:“^5.22.0”, "sequelize-cli": "^5.5.1",但我在使用 Sequelize 6 时出错。
目前,我有这个:
数据库/setup/databaseConnection.js
// Imports
import Sequelize from "sequelize"
const connection = new Sequelize(
process.env.DATABASE_NAME,
process.env.DATABASE_USER,
process.env.DATABASE_PASSWORD,
host: process.env.DATABASE_URL,
port: process.env.DATABASE_PORT,
dialect: "mysql",
logging: false,
define:
// prevent sequelize from pluralizing table names
freezeTableName: true,
,
)
// Test connection
console.info("SETUP - Connecting database...")
connection
.authenticate()
.then(() =>
console.info("INFO - Database connected.")
)
.catch((err) =>
console.error("ERROR - Unable to connect to the database:", err)
)
export connection as default
数据库/模型/index.js
// Imports
import Sequelize from "sequelize"
// App Imports
import connection from "../setup/databaseConnection"
const models =
Language: connection.import("./language"),
Object.keys(models).forEach((modelName) =>
if ("associate" in models[modelName])
models[modelName].associate(models)
)
models.sequelize = connection
models.Sequelize = Sequelize
export models as default
数据库/模型/语言.js
module.exports = (sequelize, DataTypes) =>
const Language = sequelize.define(
"language",
/* id :
primaryKey: true,
type : DataTypes.INTEGER
, */
name:
type: DataTypes.STRING,
,
code:
type: DataTypes.STRING,
,
is_active:
type: DataTypes.BOOLEAN,
,
,
)
Language.associate = function (models)
// Language has Many Bucket
models.Language.hasMany(models.Bucket,
foreignKey: "id",
)
return Language
但我有这个错误:
formation-api/database/models/index.js:17
Language: _databaseConnection["default"]["import"]("./language")
^
TypeError: _databaseConnection.default.import is not a function
at Object.<anonymous> (/Users/jeremiechazelle/Sites/api/database/models/index.js:8:15)
at Module._compile (internal/modules/cjs/loader.js:1147:30)
at Module._compile (/Users/jeremiechazelle/Sites/api/node_modules/pirates/lib/index.js:99:24)
at Module._extensions..js (internal/modules/cjs/loader.js:1167:10)
at Object.newLoader [as .js] (/Users/jeremiechazelle/Sites/api/node_modules/pirates/lib/index.js:104:7)
at Module.load (internal/modules/cjs/loader.js:996:32)
at Function.Module._load (internal/modules/cjs/loader.js:896:14)
at Module.require (internal/modules/cjs/loader.js:1036:19)
at require (internal/modules/cjs/helpers.js:72:18)
at Object.<anonymous> (/Users/jeremiechazelle/Sites/api/resolvers/Queries/User.js:2:1)
[nodemon] app crashed - waiting for file changes before starting...
我使用: "续集": "^6.1.0", "sequelize-cli": "^6.0.0"
【问题讨论】:
【参考方案1】:Sequelize ^6.x 不再支持 sequelize.import。他们说你应该使用 require 来代替。
我了解到您必须手动导入模型。
这里是一个使用 require 的例子
./models/index.js
const dotenv = require('dotenv');
const fs = require('fs');
const path = require('path');
const Sequelize, DataTypes = require('sequelize');
const filebasename = path.basename(__filename);
const db = ;
// Get env var from .env
dotenv.config()
const DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_FORCE_RESTART = process.env;
const config =
host: DB_HOST,
dialect: 'mysql',
dialectOptions:
charset: 'utf8',
const sequelize = new Sequelize(DB_NAME, DB_USER, DB_PASS, config);
fs
.readdirSync(__dirname)
.filter((file) =>
const returnFile = (file.indexOf('.') !== 0)
&& (file !== filebasename)
&& (file.slice(-3) === '.js');
return returnFile;
)
.forEach((file) =>
const model = require(path.join(__dirname, file))(sequelize, DataTypes)
db[model.name] = model;
);
Object.keys(db).forEach((modelName) =>
if (db[modelName].associate)
db[modelName].associate(db);
);
db.sequelize = sequelize;
db.Sequelize = Sequelize;
const sequelizeOptions = logging: console.log, ;
// Removes all tables and recreates them (only available if env is not in production)
if (DB_FORCE_RESTART === 'true' && process.env.ENV !== 'production')
sequelizeOptions.force = true;
sequelize.sync(sequelizeOptions)
.catch((err) =>
console.log(err);
process.exit();
);
module.exports = db;
./models/User.js
'use strict';
import cryp from 'crypto';
module.exports = function (sequelize, DataTypes)
const User = sequelize.define('User',
email:
type: DataTypes.STRING(50),
allowNull: false,
unique: true,
validate:
isEmail: msg: "Please enter a valid email addresss"
,
isEmail: true
,
password_hash: type: DataTypes.STRING(80), allowNull: false ,
password:
type: DataTypes.VIRTUAL,
set: function (val)
//this.setDataValue('password', val); // Remember to set the data value, otherwise it won't be validated
this.setDataValue('password_hash', cryp.createHash("md5").update(val).digest("hex"));
,
validate:
isLongEnough: function (val)
if (val.length < 8)
throw new Error("Please choose a longer password");
,
role:
type: DataTypes.INTEGER,
allowNull: false
,
active:
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 1
,
classMethods:
associate: function (models)
// User.belongsTo(models.Department, foreignKey: allowNull: false );
// User.belongsTo(models.Position, foreignKey: allowNull: false );
// User.belongsTo(models.Profile, foreignKey: allowNull: false );
// User.hasMany(models.Report, foreignKey: allowNull: false );
// User.hasMany(models.Notification, foreignKey: allowNull: false );
// User.hasMany(models.Response, foreignKey: allowNull: false );
,
timestamps: true,
// don't delete database entries but set the newly added attribute deletedAt
// to the current date (when deletion was done). paranoid will only work if
// timestamps are enabled
paranoid: false,
// don't use camelcase for automatically added attributes but underscore style
// so updatedAt will be updated_at
underscored: true
);
return User;
;
.env
DB_HOST=localhost
DB_USER=wilo087
DB_PASS=temp
DB_NAME=database_name
DB_FORCE_RESTART=true #Remove and create tables
完整示例: https://github.com/wilo087/pethome_raffle_backend/tree/develop
【讨论】:
谢谢@wilo087 的回答,请问有代码示例吗? 很遗憾,您不能在带有 ES 模块的最新 Node 版本中使用“require”。【参考方案2】:像这样:
import Sequelize from 'sequelize'
import userModel from './user'
import messageModel from './message'
const sequelize = new Sequelize(process.env.DATABASE, process.env.DATABASE_USER, process.env.DATABASE_PASSWORD,
dialect: 'postgres'
)
const models =
User: userModel(sequelize, Sequelize.DataTypes),
Message: messageModel(sequelize, Sequelize.DataTypes)
【讨论】:
【参考方案3】:我遇到了同样的问题并解决了:
版本 5.25.1 const model = sequelize["import"](path.join(__dirname, file));
版本 6.2.1 const model = require(path.join(__dirname, file))(sequelize, Sequelize);
希望对你有帮助
【讨论】:
【参考方案4】:我试图找到一种方法来使用类定义的方式来做到这一点。我就是这样做的!
models/trading-view-alert.js
const Model, DataTypes = require('sequelize');
module.exports = function(sequelize)
class TradingViewAlert extends Model
return TradingViewAlert.init(
action:
type: DataTypes.STRING,
allowNull: false
,
strategy_num_contracts:
type: DataTypes.STRING,
allowNull: false
,
strategy_orderid:
type: DataTypes.STRING,
allowNull: false
,
strategy_price:
type: DataTypes.STRING,
allowNull: false
,
strategy_comment :
type: DataTypes.STRING,
allowNull: false
,
strategy_position_size:
type: DataTypes.STRING,
allowNull: false
,
sequelize,
modelName: 'TradingViewAlert'
);
;
你的文件使用了model.js
const TradingViewAlert = require('../models/trading-view-alert');
const TradingViewAlertModel = TradingViewAlert(sequelize);
然后只需调用 await TradingViewAlertModel.sync( alter: true );
sync 命令当然需要在 async() 函数中才能工作,然后就可以使用带有 sequelize 6 的类和单独的文件中的模型!
【讨论】:
【参考方案5】:如果你有很多模型,写一个导入方法可能会很有用:
const autoImport = function(path)
let defineCall = require(path);
if (typeof defineCall === 'object' && defineCall.__esModule)
// Babel/ES6 module compatability
defineCall = defineCall['default'];
return defineCall(sequelize, Sequelize.DataTypes);
;
所以不要这样:
...
const models =
Language: connection.import("./language"),
...
你可以这样做:
...
const models =
Language: autoImport("./language"),
...
拥有 50 多个模型,我们更容易迁移到 Sequelize 6。
【讨论】:
以上是关于Sequelize 6 从文件中导入模型的主要内容,如果未能解决你的问题,请参考以下文章