Создать базу данных в Knex миграции

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

knexfile.js

'use strict';

require('dotenv').config({ path: 'process.env' });

const config =  {
  client: 'pg',
  connection: {
    host: process.env.DB_URL,
  },
};


module.exports = config;

файл миграции:

'use strict';

exports.up = function(knex, Promise) {
  return knex.raw('CREATE DATABASE asd');
};

exports.down = function(knex, Promise) {
  return knex.raw('DROP DATABASE asd');
};

exports.config = {
  transaction: false
};

До этого момента он работает правильно, но когда я добавляю database в конфигурацию knexfile, он не может выполнить миграцию, поскольку Knex пытается подключиться к несуществующей базе данных.

Я также попытался использовать новый экземпляр Knex для этой единственной миграции, например:

exports.up = function(_, Promise) {
  // Remove database from config so Knex won't try to connect
  // to a non existing database.
  const config = require(process.cwd() + '/knexfile');
  config.connection.database = null;
  const knex = require('knex')(config);

  return knex.raw('CREATE DATABASE asd');
};

Но knex уже инициализирован перед миграцией, поэтому он не работает с той же ошибкой:

error: database "asd" does not exist

Есть идеи о том, как создать базу данных из миграции Knex? Я открыт для любых передовых методов создания базы данных, которая может обрабатывать URL-адреса db для разных сред.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
8
0
7 162
3

Ответы 3

Knex действительно не поддерживает легкое создание баз данных.

Прежде всего, выполняющиеся миграции должны создать таблицу, содержащую информацию о выполненных миграциях, поэтому база данных должна существовать до выполнения миграции.

Обычно вы хотели бы иметь другой файл конфигурации для создания баз данных с пользователем с достаточными привилегиями для создания баз данных и который подключается, например, к база данных называется postgres или template1.

Это можно сделать, просто создав простой скрипт, который гарантирует создание БД перед запуском миграции.

Также существует инструмент knex-db-manager (написанный в основном мной), который может помочь в задачах создания пользователей / баз данных-владельцев баз данных.

Я добавил сценарий postinstall, который запускает такой сценарий:

'use strict';

async function createDatabase() {
  const config = require(process.cwd() + '/knexfile');
  config.connection.database = null;
  const knex = require('knex')(config);

  await knex.raw('CREATE DATABASE asd');
  await knex.destroy();
}

createDatabase();

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

Что вы думаете об этом подходе?

распространенным вариантом использования будет временная база данных для запуска интеграционных тестов с

davidmwhynot 31.12.2020 04:55

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

Сохранить как migrate.js

const Knex = require('knex')

// You can dynamically pass the database name
// as a command-line argument, or obtain it from
// a .env file
const databaseName = 'database_name'

const connection = {
  host: 'localhost',
  user: 'root',
  password: 'password'
}

async function main() {
  let knex = Knex({
    client: 'mysql',
    connection
  })
  
  // Lets create our database if it does not exist
  await knex.raw('CREATE DATABASE IF NOT EXISTS ??', databaseName)
  

  // Now that our database is known, let's create another knex object
  // with database name specified so that we can run our migrations
  knex = Knex({
    client: 'mysql',
    connection: {
      ...connection,
      database: databaseName,
    }
  })

  // Now we can happily run our migrations
  await knex.migrate.latest()

  // Done!!
}

main().catch(console.info).then(process.exit)

Теперь вы можете запустить свой скрипт

node migrate.js

Вы можете использовать файл .env для хранения своей конфигурации или передать их в качестве аргументов командной строки.

Другие вопросы по теме