Запрос от MySQL с использованием NodeJS - PullRequest
1 голос
/ 18 июня 2020

Я пытаюсь запросить таблицу базы данных MySQL. Я использую NodeJS / Express в качестве серверной части.

Я настроил MySQL вот так ... (Да, я проверил, подключается ли серверная часть к базе данных. У меня только что пропустил учетные данные ниже.)

const db = mysql.createConnection({
  host: '',
  user: '',
  password: '',
  database: ''
});

db.connect((error) => {
  if (error) {
    console.log(error);
  } else {
    console.log("MySQL connected.");
  }
});

Я пытаюсь упорядочить свой код, поэтому у меня есть это в файле конфигурации. Я хочу экспортировать константу db и выполнять db.query () из других файлов.

Следовательно, я сделал это.

module.exports = {
  app: app,
  db: db
};

Однако, когда мне требуется db в других файлах, выполняйте следующее

const db = require('../../server');

В нем говорится, что db.query не является функцией. Кто-нибудь знает, почему он так сказал? Кажется, я не могу правильно экспортировать его.

Спасибо.

Ответы [ 2 ]

1 голос
/ 18 июня 2020

В моем приложении я использую это так:

const mysql = require('mysql');

connection = mysql.createPool({
    host: '***',
    user: '***',
    password: '***',
    database: '***'

});

module.exports = connection;

И где мне нужно его назвать:

const conn = require('path/to/dbfile.js');

Затем просто используйте:

conn.query('SELECT * FROM TEST', function (err, rows) {
    if (err)
        return err;
    return rows;
});
0 голосов
/ 18 июня 2020

Короткий ответ

Вероятно, у вас круговая зависимость, т.е. у вас есть файл a, который require s file b, но файл b также require s file a. В сочетании с использованием module.exports = something (вместо изменения существующего объекта exports) это приводит к ситуации, когда один из модулей получит пустой объект, возвращенный из require другого (кажется, что ни один из его экспортов не существует там).

Быстрое исправление, скорее всего, заменит module.exports = { app, db } на exports.app = app; exports.db = db или Object.assign(exports, { app, db }).

Относительно того, почему, и какие другие варианты существуют в случае, если это не лучшее решение, читайте ниже.

Длинный ответ

Звучит так, как будто у вас проблема с круговой зависимостью.

Позвольте мне объяснить, и терпите меня, мы ' В конце концов я займусь вашей проблемой.

Видите ли, каждый модуль начинается с пустого объекта как module.exports (также доступен как exports). Если вы только измените этот объект, выполнив exports.something = something (или module.exports.something = something), во многих случаях все может работать даже с циклической зависимостью на верхнем уровне, если свойства объекта экспорта доступ только позже. Например:

/* a.js */
const b = require('./b')

exports.getX = function () {
  return b.getY() * 2
}

exports.getZ = function () {
  return 5
}
/* b.js */
const a = require('./a')

exports.getY = function () {
  return a.getZ() * 3
}
/* main.js */
const a = require('./a')

console.log(a.getX()) // Returns 30

Здесь у нас есть круговая зависимость (a зависит от b, но b также зависит от a). Тем не менее, он работает.

Приведенный выше код работает, потому что при вычислении a.js его объект exports уже будет существовать, а когда он требует b.js, а b.js снова требует a.js, тогда, даже если a.js еще даже не завершил выполнение своего кода верхнего уровня, переменной a в b.js уже может быть присвоен объект exports из a.js. На данный момент это пустой объект, но к моменту запуска строки return a.getZ() * 3 у объекта будет установлено свойство getZ.

  1. main требуется a
  2. a требует b
  3. b требует a и получает объект, который равен в настоящее время пустой
  4. b определяет getY при экспорте и возврате
  5. a определяет getX и getZ в своем экспорте (который является тем же самым объектом, на который b уже ссылается!) и возвращает
  6. main звонки a.getX()
  7. a.getX звонки b.getY
  8. b.getY только теперь получает доступ к свойству getZ из a, которое уже существует (это было установлено на шаге 5).

Обратите внимание, что это не сработало бы, если бы мы написали const { getZ } = require('./a'), потому что тогда к свойству getZ был бы доступ уже на шаге 3, когда он не

Но, точно так же, он бы тоже перестал работать, если бы мы написали a.js вот так:

const b = require('./b')

function getX () {
  return b.getY() * 2
}

function getZ () {
  return 5
}

module.exports = { getX, getZ }

Большая разница вот это , теперь мы переназначаем объект экспорта ! Итак, объект, который b получает на шаге 3, является исходным (пустым) объектом, но затем мы переназначаем его новому объекту (вместо изменения существующего объекта), и код в b никогда не имеет шансов чтобы получить ссылку на этот объект! Тогда у вас будет такая точная ситуация: A require дает вам пустой объект, и попытка вызвать a.getZ завершится ошибкой с a.getZ is not a function (потому что это undefined).

(Кстати , module.exports = something это не то же самое, что exports = something, потому что последний переназначает локальную переменную exports и не меняет то, что другие модули будут видеть как экспорт из вашего!)

Мое предположение прямо сейчас заключается в том, что у вас здесь аналогичная проблема - что файл, который выполняет соединение с БД, требует файла, который использует соединение с БД, но и наоборот.

Теперь у вас есть два варианта:

  • Заменить module.exports = { app, db } на exports.app = app; exports.db = db или Object.assign(exports, { app, db }) - оба варианта изменяют существующий объект экспорта вместо его замены.

Первый вариант, вероятно, самый простой немедленное решение проблемы. Но я не знаю остальной части вашего кода, поэтому могут быть другие препятствия, которые мешают этому решению быть жизнеспособным.

Итак, позвольте мне подробно объяснить второй вариант, потому что он может решить проблему тоже часто.

Пример второго варианта:

/* a.js */
let b

function getX () {
  return b.getY() * 2
}

function getZ () {
  return 5
}

function init () {
  b = require('./b')
}

module.exports = { init, getX, getZ }
/* b.js */
const a = require('./a')

function getY = function () {
  return a.getZ() * 3
}

module.exports = { getY }
/* main.js */
const a = require('./a')
a.init()

console.log(a.getX()) // Returns 30

Этот код теперь работает , хотя он переназначает module.exports, потому что теперь все происходит в другом порядке:

  1. main требует a
  2. a заменяет свой объект экспорта на тот, который содержит init, getX и getZ и возвращает [обратите внимание, что эта часть кода ранее выполнялась намного позже]
  3. main вызывает a.init()
  4. a.init требует b
  5. b требует a и получает свой окончательный объект экспорта со всеми методами [обратите внимание, что ранее он получал еще не заполненный объект, потому что a также еще не был полностью загружен!]
  6. b заменяет его объект экспорта с одним, который содержит getY и возвращает
  7. a.init возвращает
  8. С этого момента все работает, потому что оба a и b уже имеют ссылки на полностью заполненные объекты экспорта друг друга

Другой способ реализовать второй вариант «требования в более поздний момент времени» - это require другой модуль внутри экспортированной функции, который уже используется, но это может иметь свои недостатки (например, дублирование кода, если он требуется во многих функциях и немного медленнее, потому что require приходится вызывать снова и снова). В нашем примере это будет означать следующее:

/* b.js */

function getY () {
  const a = require('./a')
  return a.getZ() * 3
}

module.exports = { getY }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...