Сегодня я завершил еще одну миграцию. Я перешел с тестовой базы данных 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.