Я пишу NodeJS API с express, который использует Sequelize в качестве ORM для подключения к базе данных postgres.
У меня есть несколько файлов API, содержащих функции конечных точек для каждой модели, и Я группирую связанные функции в этих файлах.
В этих файлах я загружаю соединение db, требуя папку models
, которая содержит все определения модели, и индексный файл, который создает и экспортирует соединение базы данных с модели.
Я создаю это в верхней части любого файла, которому требуется доступ к базе данных. Моя проблема в том, что когда я вхожу в конечную точку, я могу получить доступ к соединению с базой данных идеально. Но когда я вызываю любую функцию из другого файла, который также обращается к базе данных, все мои модели из файла required
имеют значение undefined
, и выдается ошибка.
/* api/fooApi.js */
const db = require('../models')
const logApi = require('../logApi')
async function createFoo(req, res, next) {
try {
// db.foo and db.log are defined here, and accessible
const foo = await db.foo.create(req.body)
const log = await logApi.logCreation('foo', foo)
}
}
module.exports = { createFoo }
/* api/logApi.js */
const db = require('../models')
async function logCreation(recordType, record) {
// db.foo and db.log are not defined here when the function is called from fooApi.js
const log = await db.log.create({
event: 'create',
type: recordType,
details: `${recordType} record created by user ${record.createdBy}`
})
return log
}
module.exports = { logCreation }
Когда я вхожу в конечную точку функция createFoo()
, у меня есть полный доступ ко всему, что я ожидаю в db
, включая db.foo.create()
. Но в logCreation()
я не могу получить доступ к этим же функциям.
Многие разные модели получат доступ к функции logCreation
, поэтому ее необходимо определить в одном месте. Оператор require
в верхней части файла точно такой же, как в fooApi
, но когда я отлаживаю функцию, db
является пустым объектом без каких-либо свойств, которые он должен иметь.
Если я передам db в качестве аргумента logCreation
, то функция будет работать, но я бы хотел этого избежать, если смогу, так как это потребовало бы серьезной реструктуризации. До того, как все было настроено таким образом, в каждом файле API было следующее:
let db = null
function init (dbConn) {
db = dbConn
}
При установке я вызывал init () в каждом файле API, используя тот же экземпляр, что и аргумент. Тем не менее, это был очень неуклюжий способ сделать то, от чего я хотел отойти.
Поэтому мой вопрос: как правильно настроить Sequelize, чтобы я мог получить доступ к базе данных по нескольким файлам? Я использую неявные транзакции, используя пространство имен и cls-hooked
, как указано в документации.