Czasem mamy potrzebę porównać dwie podobne bazy danych pod kątem różnic struktury i danych. Przykładowo chcemy zaktualizować projekt lokalnie, a na serwer produkcyjny chcemy zaaplikować samą migrację z przygotowane wcześniej pliku .sql, i do tego właśnie służy fajne narzędzie o nazwie DBDiff.
Narzędzie to aplikacja napisana w php, pobierzemy je ze strony https://github.com/DBDiff/DBDiff.
Instalacja jest bardzo prosta, najpierw w pliku php.ini (u mnie dla php 7.3 jest to /etc/php/7.3/cli/php.ini) dodajemy:
phar.readonly = false
a następnie odpalamy kolejno:
git clone git@github.com:DBDiff/DBDiff.git cd DBDiff ./build sudo mv dist/dbdiff.phar /usr/local/bin/dbdiff
Po tej operacji mamy globalnie w systemie zainstalowaną aplikację i możemy zaczynać.
Najlepiej jest utworzyć sobie plik z konfiguracją o nazwie .dbdiff, dzięki temu nie będziemy musieli w terminalu wpisywać tych danych.
server1: host: localhost password: dbpass port: 3306 user: dbuser server2: host: localhost password: dbpass port: 3306 user: dbuser
Następnie w katalogu gdzie jest nasz plik konfiguracyjne .dbdiff, odpalamy:
dbdiff server1.db1:server2.db2 --nocomments=false --type=schema
gdzie:
server1 | nazwa serwera nr. 1 w pliku .dbdiff |
server2 | nazwa serwera nr. 2 w pliku .dbdiff |
db1 | nazwa bazy danych na serwerze nr. 1 |
db2 | nazwa bazy danych na serwerze nr. 2 |
–type | typ migracji, schema, data lub all |
–nocomments | false lub true, informujemy czy chcemy komentarze |
Wynikiem odpalenia komendy jest podsumowanie:
ℹ Now calculating schema diff for table `ps_timezone` ℹ Now calculating schema diff for table `ps_translation` ℹ Now calculating schema diff for table `ps_warehouse` ℹ Now calculating schema diff for table `ps_warehouse_carrier` ℹ Now calculating schema diff for table `ps_warehouse_product_location` ℹ Now calculating schema diff for table `ps_warehouse_shop` ... ℹ Now calculating schema diff for table `ps_webservice_account` ℹ Now calculating schema diff for table `ps_webservice_account_shop` ℹ Now calculating schema diff for table `ps_webservice_permission` ℹ Now calculating schema diff for table `ps_zone` ℹ Now calculating schema diff for table `ps_zone_shop` ℹ Now generating UP migration ℹ Writing migration file to /var/www/dbdiff/migration.sql ✔ Completed
…oraz plik migration.sql, który zawiera listę zapytań SQL, które musimy odpalić na docelowym serwerze.
Poniżej przykład porównania dwóch wersji PrestaShop 1.7.1.0 oraz 1.7.8.0.
#---------- UP ---------- CREATE TABLE `ps_blockwishlist_statistics` ( `id_statistics` int unsigned NOT NULL AUTO_INCREMENT, `id_cart` int unsigned DEFAULT NULL, `id_product` int unsigned NOT NULL, `id_product_attribute` int unsigned NOT NULL, `date_add` datetime NOT NULL, `id_shop` int unsigned DEFAULT '1', PRIMARY KEY (`id_statistics`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; CREATE TABLE `ps_currency_lang` ( `id_currency` int unsigned NOT NULL, `id_lang` int unsigned NOT NULL, `name` varchar(255) NOT NULL, `symbol` varchar(255) NOT NULL, `pattern` varchar(255) DEFAULT NULL, PRIMARY KEY (`id_currency`,`id_lang`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CREATE TABLE `ps_wishlist_product_cart` ( `id_wishlist_product` int unsigned NOT NULL, `id_cart` int unsigned NOT NULL, `quantity` int unsigned NOT NULL, `date_add` datetime NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; CREATE TABLE ... ALTER TABLE `ps_attribute` DROP CONSTRAINT `FK_6C3355F967A664FB`; ALTER TABLE `ps_lang_shop` DROP CONSTRAINT `FK_2F43BFC7274A50A0`; ALTER TABLE `ps_attribute_group_lang` DROP CONSTRAINT `FK_4653726C67A664FB`; ALTER TABLE `ps_attribute_lang` DROP CONSTRAINT `FK_3ABE46A77A4F53DC`; ALTER TABLE `ps_attribute_group_shop` DROP CONSTRAINT `FK_DB30BAAC274A50A0`; ALTER TABLE `ps_translation` DROP CONSTRAINT `FK_ADEBEB36BA299860`; ALTER TABLE `ps_attribute_shop` DROP CONSTRAINT `FK_A7DD8E677A4F53DC`; ALTER TABLE `ps_attribute_group_shop` DROP CONSTRAINT `FK_DB30BAAC67A664FB`; ALTER TABLE `ps_tab_lang` DROP CONSTRAINT `FK_CFD9262DED47AB56`; ALTER TABLE `ps_attribute_shop` DROP CONSTRAINT `FK_A7DD8E67274A50A0`; ALTER TABLE `ps_lang_shop` DROP CONSTRAINT `FK_2F43BFC7BA299860`; #---------- DOWN ----------
Podsumowanie
Niestety narzędzie to nie jest idealne, działa w prosty sposób i nie uwzględnia np. zmiany nazwy tabel czy przeniesienie kolumn do innych tabel — dlatego bardzo ważne jest, żeby przed odpaleniem pliku migration.sql, dobrze się mu przyjrzeć i sprawdzić jakie zmiany wprowadzi w naszej bazie.