Sequelize Создать базу данных

Есть ли способ сделать секвестизацию создания базы данных, к которой я пытаюсь подключиться, если она не существует?

У меня есть необработанный экземпляр MySQL, и я возвращаю эту ошибку:

ER_BAD_DB_ERROR: Unknown database 'mytest'

Я хотел бы обработать эту ошибку, использовать предоставленные мной creds (или другой набор создает с разрешениями на создание) и запустить CREATE DATABASE mytest.

Ответ 1

У меня может быть разумное решение. Я уверен, что это может быть написано более чисто, хотя.

В этом примере я использую Postgres, ответ будет немного отличаться для MySQL. Я сильно заимствую из этого ответа: node -postgres создать базу данных

В database.js У меня есть следующая функция init

var Sequelize = require('sequelize'),
    pg = require('pg');

module.exports.init = function(callback) {
    var dbName = 'db_name',
        username = 'postgres',
        password = 'password',
        host = 'localhost'

    var conStringPri = 'postgres://' + username + ':' + password + '@' + host + '/postgres';
    var conStringPost = 'postgres://' + username + ':' + password + '@' + host + '/' + dbName;

    // connect to postgres db
    pg.connect(conStringPri, function(err, client, done) { 
        // create the db and ignore any errors, for example if it already exists.
        client.query('CREATE DATABASE ' + dbName, function(err) {
            //db should exist now, initialize Sequelize
            var sequelize = new Sequelize(conStringPost);
            callback(sequelize);
            client.end(); // close the connection
        });
    });
};

Функция init создает базу данных до вызова функции secelize. Сначала он открывает соединение с postgres и создает базу данных. Если база данных уже существует, будет выдана ошибка, которую мы игнорируем. После его создания мы инициализируем sequelize и отправляем его на обратный вызов. Важно отметить, что если база данных уже существует, она не будет перезаписана.

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

require('./server/config/database.js').init(function(database) {
  require('./server/config/passport.js')(passport, database);
});

Ответ 2

В моем случае я использовал sqlite, но идея была такой же. Сначала мне нужно было создать базу данных с помощью sqlite3.

const sqlite = require('sqlite3');
const db = new sqlite.Database('/path/to/database.sqlite');
const sequelize = new Sequelize('database', '', '', {
  dialect: 'sqlite',
  storage: '/path/to/database.sqlite',
  ...
});

Ответ 3

Я закончил тем, что использовал пакет mysql2, вот что я сделал..

const mysql = require('mysql2/promise');

mysql.createConnection({
    user     : config.sequelize.username,
    password : config.sequelize.password
}).then(() => {
    connection.query('CREATE DATABASE IF NOT EXISTS myRandomDb;').then(() => {
        // Safe to use sequelize now
    })
})

После этого я могу подключиться к этой базе данных, используя sequelize.

Ответ 4

У меня не было этой проблемы с Postgresql, но у меня была проблема с MySQL. Решение было создание pre-migrate скрипта и запустить его перед миграцией sequelize, здесь часть моего package.json:

"db:pre-migrate": "node scripts/createDB.js",
"db:migrate": "npm run db:pre-migrate && node_modules/.bin/sequelize db:migrate",

и аналогично тому, что было предложено в некотором ответе здесь, вы можете создать этот createDB.js используя такие модули, как node-postgres или mysql (или любой другой, который подключается к mysql с необработанными запросами):

const mysql = require('mysql2/promise');

const dbName = process.env.DB_SCHEMAS || "YOUR_DB";

mysql.createConnection({
    host: process.env.DB_HOST || "127.0.0.1",
    port: process.env.DB_PORT || "3306",
    user     : process.env.DB_USER || "root",
    password : process.env.DB_PASSWORD || "root",
}).then( connection => {
    connection.query('CREATE DATABASE IF NOT EXISTS ${dbName};').then((res) => {
        console.info("Database create or successfully checked");
        process.exit(0);
    })
})