
- Data wpisu: 2009-05-28
- Tagi: Bazy danych, databases.yml, Multidatabase, ORM, PHP, PostgreSQL, Propel, propel.ini, schema, SQL, sqldb.map, Symfony, yml
W aplikacjach internetowych czasami musimy wykorzystać w jednym serwisie wiele baz danych, nieraz nawet wiele różnych baz danych. Mój wpis będzie prezentował proste przykłady użycia wielu baz z wykorzystaniem frameworka Symfony. Dla przykładu użyje bazy danych PostgreSQL oraz ORM Propela 1.3.
W przykładzie wykorzystam 2 tabele: “users” z bazy “db1″ (załóżmy, że to główna bazy serwisu z użytkownikami) i “requests” z bazy “db2″ (baza w której zapisywane są statystyki z żądań do aplikacji). Modele wygenerowane będą dla bazy PostgreSQL. W kolejnym etapie zaprezentuje w jaki sposób można załadować przykładowe dane pochodzące z data/fixtures.
Definiowanie baz w pliku databases.yml
Edytujemy config/databases.yml
all:
propel:
class: sfPropelDatabase
param:
classname: PropelPDO
dsn: pgsql:dbname=db1;host=panic user=db1 password=db1
hostspec: pgsql
port: 5432
encoding: utf8
stat:
class: sfPropelDatabase
param:
classname: PropelPDO
dsn: pgsql:dbname=db2;host=panic user=db2 password=db2
hostspec: pgsql
port: 5432
encoding: utf8
Pierwszym krokiem jest zdefiniowanie połączeń do baz danych. Główną nazwę połączenia będzie “propel” a drugą “stat”
Ustawienie pliku propel.ini
propel.database = pgsql propel.database.driver = pgsql propel.database.url = pgsql:dbname=db1;host=panic user=db1 password=db1
W pliku propel.ini ustawiamy połączenie z główną bazę danych. “propel.database” odpowiada za generowanie kodu SQL dla danych baz, np.: MySQL, PostgreSQL, Oracle. Jeśli chcemy generować SQL dla wybranego typu bazy, to musimy zmienić na odpowiednią wartość. Można to uzyskać z linii koment ustawiajac –phing-arg
Przykład dla MySQLa:
./symfony propel:build-all --no-confirmation --connection=stat --phing-arg="Dpropel.database=mysql"
Przykład dla Oracle:
./symfony propel:build-all --no-confirmation --connection=stat --phing-arg="Dpropel.database=oracle"
Definiowanie tabel w config/schema.yml
Jak w przykładzie z optymalizacją Propela dobrym nawykiem jest rozdzielenie różnego typu struktur na osobne pliki schema.yml. Główną definicja tabel można zapisać w pliku schema.yml a dodatkową strukturę bazy w osobnym pliku, np w pliku stat_schema.yml.
Plik config/schema.yml
propel:
users:
id: { type: integer, required: true, primaryKey: true, autoincrement: true }
created_at: { type: timestamp }
name: { type: varchar, size: 255 }
surname: { type: varchar, size: 255 }
Plik config/stat_schema.yml
stat:
_attributes: { package: lib.stat_model }
requests:
id: { type: integer, required: true, primaryKey: true, autoincrement: true }
created_at: { type: timestamp }
module: { type: varchar, size: 255 }
action: { type: varchar, size: 255 }
W pliku stat_schema.yml, użyłem package: lib.stat_model – czyli miejsce, w którym zostaną wygenerowane modele wykorzystujące bazę “db2″, lib.stat_model = lib/stat_model.
Po zdefiniowaniu struktur i baz przechodzimy do generowania modeli i stworzenia struktur tabel w bazach danych.
Generowanie modeli i struktur baz danych dla “db1″ i “db2″
./symfony propel:build-all --no-confirmation
Modele dla baz danych zostały wygenerowane. Struktura tabel została stworzona tylko w pierwszej bazie “db1″ - ponieważ to połączenie jest domyślne. Aby stworzyć strukturę tabel w bazie “db2″ musimy wymusić połączenie z bazą “db2″ (czyli połączenie o nazwie “stat”).
./symfony propel:build-all --no-confirmation –connection=stat
Przykład wykorzystania modeli
Przykłady:
$obj1 = UsersPeer::retrieveByPK(1); $obj2 = RequestsPeer::retrieveByPK(1);
Wykorzystując model nie musimy podawać połączenia, chyba że chcemy aby dany model był wykorzystany jawnie do “innej” bazy, “innej” mam tutaj na myśli bazy danych o takiej samej strukturze tabeli jaka jest zdefiniowana w modelu.
Ładowanie przykładowych danych (data/fixtures)
Podobnie jak w przypadku definicji struktur bazy danych rozdzielamy ładowanie danych. Dla bazy “db1” będzie to katalog data/fixtures a dla bazy “db2” data/stat_fixtures
Wywołanie tasków - dla domyślnej bazy danych “db1″ :
./symfony propel:data-load
Ładowanie danych do bazy “db2″ wymaga podania odpowiedniego połączenie i ustawienia katalogu z którego dane będą wczytywane.
./symfony propel:data-load --connection=stat --dir="data/stat_fixtures"
Można definiować n takich baz. Jeśli np. chcielibyśmy operować na takich samych tabelach w różnych bazach danych to możemy w modelach wymuszać konkretne połączenia, wszystko zależy od projektu i jego wymagań.
Popularne
- Doda i Nergal - Jak to odbiorą fani zespołu Behemoth?
- Koncert Rammstein - Katowice / Spodek
- Symfony - przyśpieszanie Propela z wykorzystaniem widoków (view) baz danych
- Symfony, Propel, PostgreSQL - Multi database (obsługa wielu baz danych w aplikacji)
- Gentoo - Instalacja PostgreSQL 8.3.x i PHP
- Social Media jednak nie dla wszystkich, na przykładzie SuperExpress.
- pgAdmin v1.10.0 released
- Symfony - Propel Lazy Load

Bardzo ciekawa notka, keep on the good work chciało by się powiedzieć
Przy okazji zauważyłem, że toolbar symfony pokazuje zapytania tylko dla głównego połączenia. Jest jakaś szansa żeby pokazywał zapytania do obu baz?
Komentarz - autor: Theq — 2009-05-29 @ 14:41
Hmm wsumie to nie zwrocilem uwagi na to. Mozliwe ze tylko dla polaczenia 2 bazy trzeba dodac debug i beda sie SQLki pokazywac
Komentarz - autor: admin — 2009-05-31 @ 01:06
Ano, zgadza się.
Komentarz - autor: Theq — 2009-06-01 @ 07:11
A da się stworzyć Model tak aby łąćzył tabele z 2 róznych baz w związku n:m
Komentarz - autor: Kowalikus — 2009-07-23 @ 13:52