Skip to content

Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1

by zergu on Grudzień 15th, 2008 Blip Facebook Flaker Twitter Wykop

Jako, że w MySQL nie dzieje się najlepiej postanowiliśmy zmigrować jeden z naszych projektów na Postgresa. Bazuje on na Symfony 1.1, co oznacza starego Propela 1.2.

Samo przestawienie połączenia nie stwarzało większych problemów, wystarczyło w databases.yml i propel.ini przerobić mysql na pgsql:

all:
  propel:
    class:          sfPropelDatabase
    param:
    persistent:       true
    phptype:          pgsql
…
propel.database            = pgsql
propel.database.createUrl  = pgsql://zdzislaw@localhost/
propel.database.url        = pgsql://zdzislaw@localhost/piwo

Przebudowanie modelu, utworzeniu bazy i jej struktury również wykonało się bez problemu, ale to był koniec tego dobrego.

Brak SERIAL

Niestety, propelowy generator skryptu SQL tworzącego schemat bazy nie uraczył nas typem SERIAL przy identyfikatorach, jednakże w samej aplikacji nie stwarza to problemów, ponieważ sekwencje i bez tego są wykorzystywane. Także trzeba po prostu uważać podczas zabawy w CLI Postgresa, gdy mogą one doprowadzić do anomalii z identyfikatorami.

Dane binarne pobierane „ręcznie”

Drobny problem pojawił się w miejscach, gdzie pobieraliśmy dane binarne (BLOB/BYTEA) własnym zapytaniem, omijając wbudowany we framework Active Record. Dane takie trzeba było dodatkowo „od-eskejpować” funkcją stripcslashes.

AKTUALIZACJA: Po aktualizacji projektu do Symfony 1.2 (chociaż tutaj właściwie chodzi o aktualizację Propela do wersji 1.3) okazało się, że żadne stripcslashes nie będzie potrzebne, ponieważ dane binarne (blob) są pobierane jako… stream. Innymi słowy, przy zapytaniach tworzonych samodzielnie, do akcji musiała wkroczyć funkcja stream_get_contents.

GROUP BY

Najwięcej problemów sprawiło grupowanie, ponieważ PostgreSQL ostro trzyma się standardów i wymusza podanie wszystkich używanych kolumn w klauzuli GROUP BY. MySQL natomiast „po cichu” sam sobie je dołączał. Różnicę w zachowaniu prezentuje poniższy (nie mający większego sensu) przykład:

psql=# select sum(id), id from users;
ERROR:  column "users.id" must appear in the GROUP BY clause
or be used in an aggregate function
mysql>  select sum(id), id from users;
+---------+----+
| sum(id) | id |
+---------+----+
|  45     |  1 |
+---------+----+

CONCAT

Łącznie ciągów znaków odbywa się całkiem inaczej w MySQL i PgSQL. W tym pierwszym wykonuje się to za pomocą funkcji CONCAT(), natomiast w drugim wykorzystuje się operator ||. Także trzeba było wykonać małą robótkę ręczną.

FORMAT

W naszym kodzie używaliśmy MySQL-owego FORMAT(), aby ograniczyć liczbę cyfr po przecinku, którego w Postgresie nie ma. Można by tutaj użyć funkcji ROUND(), obecnej i tu i tu, jednak zdecydowaliśmy się przenieść rozwiązanie tego problemu do warstwy języka programowania.

LIKE

LIKE w Postgresie, w przeciwieństwie do MySQL, rozróżnia wielkość znaków. Jednak naprawa tej przypadłości sprowadza się jedynie od zamiany LIKE na ILIKE.

Coś dziwnego

Na koniec coś, czego do końca nie udało nam się zrozumieć. Zaraz po przestawieniu konfiguracji na pgsql, strona przestała odpowiadać (a dokładniej odpowiadała, gdy połączenie z bazą przekroczyło czas oczekiwania). Niemniej jednak PostgreSQL sam w sobie działał, jak również możliwe było połączenie z „czystego” PHP. Jedynie aplikacja Symfony dziwnie się zachowywała. W logach pojawiało się następujące stwierdzenie:

Dec 4 11:20:22 myhost httpd: [wrapped: Could not connect [Native Error: pg_pconnect() [function.pg-pconnect]: Unable to connect to PostgreSQL server: server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing the request.] [User Info: host=localhost port=80 dbname='piwo' user='zdzislaw'] [User Info: Array]]

Taka sama sytuacja powtórzyła się na dwóch różnych maszynach (jednak na tym samym systemie operacyjnym). Niezrozumiałe jest to, że w czasie różnych zabaw z konfiguracją wszystko wracało do normy, jednak nie bardzo da się znaleźć konkretną przyczynę. Innymi słowy nie potrafimy zreprodukować tej sytuacji.

Krótkie podsumowanie

Migracja rozwiniętego projektu w Symfony okazała się być stosunkowo mało problematyczna. Kłopotów mogło by być jeszcze mniej, gdyby unikać rozwiązań specyficznych dla danego systemu baz danych. Ale w końcu jak często migruje się z jednej systemu zarządzania bazami danych do innego?

Podobne wpisy:

  1. Aktualizacja oprogramowania a wydajność
  2. Symfony: Paginacja przy własnych/nietypowych warunkach SQL
  3. Logowanie do pliku wszystkich zapytań w PostgreSQL

Autorzy zdjęć: Michiel van Balen

From → Bazy danych, Symfony

No comments yet

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS

Notify me of followup comments via e-mail. You can also subscribe without commenting.