Сегодня я завершил еще одну миграцию. Я перешел с тестовой базы данных SQLite3 на PostgreSQL. Процесс был довольно безболезненным и простым.

Получить PostgreSQL

Предполагая, что вы хотите провести некоторое локальное тестирование перед отправкой кода, нулевой шаг (в конце концов, мы инженеры-программисты) — получить PostgreSQL. На официальном сайте Загрузка PostgreSQL есть полезная ссылка. В итоге я остановился на Postgres.app, так как это казалось самым простым вариантом. Он также поставляется с графическим интерфейсом, который, как я полагаю, делает его более дружелюбным. В итоге я просто использовал командную строку, потому что… инженер-программист? Я действительно не знаю, почему, я только что сделал.

После того, как вы загрузите и установите его, вы можете просто запустить его, и вы будете готовы к работе. Если вы используете MacOS, вы увидите в меню логотип друга-слона, который указывает на то, что PostreSQL запущен локально. Забавный факт, я часто видел этого слона и всегда задавался вопросом, что это такое. Теперь я знаю!

Измените свой код

Далее вам нужно изменить код. Я планировал немного заранее и уже использовал Bookshelf.js с Knex.js, так что эта часть была действительно гладкой. Я бегло изучил язык PostgreSQL и, честно говоря, думаю, что даже без ORM переход с любого SQL на PostgreSQL не требует слишком большого изменения языка запросов. Но, как я уже сказал, мне повезло, что я реализовал ORM до того, как выполнил миграцию.

Ниже приведен исходный код.

var knex = require(‘knex’) ({
  client: ‘sqlite3’,
  connection: {
    host: ‘127.0.0.1’,
    user: ‘your_database_user’,
    password: ‘password’,
    database: ‘shopfull’,
    charset: ‘utf8’,
    filename: path.join(__dirname, ‘../db/shopfull.sqlite’)
  }
});

И обновленный код.

var knex = require(‘knex’) ({
  client: ‘postgresql’,
  connection: DATABASE_URL
});

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

Вы заметите, что у меня есть переменная DATABASE_URL. Поскольку технически SQLite является безсерверным, и вы никуда конкретно не подключаетесь, он просто ссылается локально с любого сервера, на котором работает приложение. Поскольку PostgreSQL не работает таким образом, мне нужно указать место, к которому он будет подключаться. Локально вроде автоматически понимал, куда идти. Это было хорошо, но явно не то, что можно было перенести в производственную среду.

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

var DATABASE_URL = process.env.DATABASE_URL || {database: ‘shopfull’}

Это приложение было в простом режиме, поэтому process.env.DATABASE_URL — это просто переменная Heroku, которую я получил, когда добавил PostgreSQL в свое приложение. Если вы когда-либо делали что-либо с MongoDB на Heroku, это почти то же самое.

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

Перенести данные

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

Сложные моменты

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

db.knex.schema.hasTable(‘items’).then(function(exists) {
  if (!exists) {
    db.knex.schema.createTable(‘items’, function (item) {
      item.increments(‘id’).primary();
      item.string(‘itemname’, 255);
      item.string(‘listid’, 255);
      item.string(‘userid’, 100);
      item.integer(‘quantity’);
      item.real(‘cost’);
      item.timestamps();
    }).then(function (table) {
      console.log(‘Created Table’, table);
    });
  }
});

Обратите внимание на жирную линию. По какой-то причине это привело к поломке приложения, когда я перешел на PostgreSQL. Несмотря на то, что в документации PostgreSQL указано, что это допустимый числовой тип, версии npm install pg он не понравился. Я не смог получить больше разъяснений по этому вопросу, но просто пошел на обходной путь.

Окончательный код, который был запущен, приведен ниже.

db.knex.schema.hasTable(‘items’).then(function(exists) {
  if (!exists) {
    db.knex.schema.createTable(‘items’, function (item) {
      item.increments(‘id’).primary();
      item.string(‘itemname’, 255);
      item.string(‘listid’, 255);
      item.string(‘userid’, 100);
      item.integer(‘quantity’);
      item.decimal(‘cost’);
      item.timestamps();
    }).then(function (table) {
      console.log(‘Created Table’, table);
    });
  }
});

Я просто изменил «действительное» на «десятичное», и это решило эту проблему.

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

Вывод

Если вы больше любите реляционные базы данных, PostgreSQL — действительно хорошая альтернатива MongoDB. Очень легко быстро приступить к работе, особенно на Heroku. Что еще более важно, он немного более надежен и почему-то кажется менее постыдным, чем интеграция с SQLite3.