konto usunięte

Temat: Ja chcę czysty SQL!

Cześć!

Mam za sobą już trochę początków z Zendem i właśnie doszedłem do wniosku, że nie chcę już mieć do czynienia z Db_Table, bo więcej z tym problemów niż pożytku, zwłaszcza gdy większość operacji wykonuję na bazie, a Db_Table najzwyczajniej nie radzi sobie z takimi skomplikowanymi zapytaniami i do tego jest nieczytelne.

Podpowie mi ktoś, jak używać czystego SQLa? Bo naczytałem się masy różnych dziwnych tutoriali i poradników, i co który gada co innego.Ten post został edytowany przez Autora dnia 25.05.13 o godzinie 10:50

konto usunięte

Temat: Ja chcę czysty SQL!

A myslales moze o Doctrine? ORM, Query Builder i wsparcie dla NativeQuery:
http://www.doctrine-project.org/

A jesli nie, to znalazlem cos takiego, przetestowalem u siebie i cos tam dziala:
http://stackoverflow.com/questions/15332671/how-to-run...

I Zend 1:
http://stackoverflow.com/questions/6161370/raw-sql-que...Ten post został edytowany przez Autora dnia 25.05.13 o godzinie 11:52

konto usunięte

Temat: Ja chcę czysty SQL!

Myślałem o Doctrine, ale ten z kolei jest już kombajnem, który wcina też trochę zasobów, no i wciąż jest to sprzeczne z moim założeniem o inteligencji takich systemów, o czym przekonałem się chwilę temu.

Zdążyłem już wyrzucić problemowy kod dla DbTable, być może błąd był po mojej stronie, nie wiem, dla człowieka, który widzi SQL, pracuje na nim kilka lat i 'widzi' co mu zwraca i w jakiej postaci jest to po prostu zbędny bajer.

No i przy obecnych doświadczeniach z tym wynalazkiem jakoś nie mogę wyobrazić sobie zapisania takiego zapytania - https://ideone.com/Ktb81W - przy użyciu ORMa.

Jeśli chodzi o to: http://framework.zend.com/manual/1.12/en/zend.db.state...
Doszedłem do wniosku, że najprościej będzie zrobić swój model i w nim prostacką funkcję do wysyłania zapytań.
Jak mniemam $db to adapter do bazy. Jak mogę go pobrać w modelu?

A application.ini mam skonfigurowany:
resources.db.adapter = "pdo_mysql"

W kontrolerach brałem po prostu $this->bootstrap, ale przecież chyba nie powinienem dziedziczyć modelu po Zend_ControllerTen post został edytowany przez Autora dnia 25.05.13 o godzinie 12:35

konto usunięte

Temat: Ja chcę czysty SQL!

Nie wiem jak to zrobic w Zend 1, bo jak rozumiem z niego korzystasz, ale znalazlem na szybko cos takiego:


$dbAdapter = Zend_Db_Table::getDefaultAdapter();


Ponoc dziala z Zendem 1.8+

Natomiast jesli chodzi o Doctrine, mozna rozne cuda wianki robic, lacznie z subselectami. Taki przyklad na szybko z subselectem:


$qb->select('l')
->from('Entity\Location', 'l')
->where('l.state = :state')
->setParameter('state', 'UT')
->andWhere($qb->expr()->notIn('u.id',
$qb->select('l2.id')
->from('Entity\Location', 'l2')
->where(l2.location_type = ?1 AND l2.popaulation < ?2)
->setParameters(array(1=> 1, 2 => 1000))
));


Chociaz patrzac na twojego, to zdecydowanie zostac przy czystym SQL niz probowac na sile zrobic z tego DQL :)Ten post został edytowany przez Autora dnia 25.05.13 o godzinie 12:54

konto usunięte

Temat: Ja chcę czysty SQL!

A to niestety tylko jedno z kilku takich zapytań, aczkolwiek nie neguję takiego zastosowania przy mniejszych i prostszych projektach.

I tak - używam Zenda 1.x. Dzięki za wskazówki, zaraz coś pokombinuję.
Krzysztof N.

Krzysztof N. CEO. Aplikacje
internetowe i
mobilne. Symfony,
Zend.

Temat: Ja chcę czysty SQL!

Przysłuchuję się dyskusji. Skłaniam się ku używaniu ORMów. Nie zawsze i wszędzie, jednak generalnie - warto. Zauważcie, że uzyskujemy możliwość przenoszenia aplikacji na inne bazy danych bez konieczności przepisywania kodu, bo serwer nie rozumie składni.

Daniel, zapytanie https://ideone.com/Ktb81W wygląda w istocie skomplikowanie, ale da się to zrobić z użyciem ORMu. Kamil już pokazał, że można tworzyć podzapytania. Trzeba tylko nieco dłużej nad tym posiedzieć.
Arkadiusz Burszczan

Arkadiusz Burszczan Programista Java

Temat: Ja chcę czysty SQL!

Może kogoś zainteresuje, kiedyś(3 lata temu) do integracjie zend 1 + Doctrine 1.2 robiłem w taki sposób.

Ja korzystam z metody _init w boostrapie


protected function _initDoctrine()
{
$this->getApplication()->getAutoloader()->pushAutoloader(array('Doctrine', 'autoload'));
spl_autoload_register(array('Doctrine', 'modelsAutoload'));
$manager = Doctrine_Manager::getInstance();
$manager->setAttribute(Doctrine::ATTR_AUTO_ACCESSOR_OVERRIDE, true);
$manager->setAttribute(Doctrine::ATTR_MODEL_LOADING, Doctrine::ATTR_LOAD_REFERENCES);
$manager->setAttribute(Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES, true);
$manager->setAttribute(Doctrine_Core::ATTR_VALIDATE, Doctrine_Core::VALIDATE_ALL);
$doctrineConfig = $this->getOption('doctrine');
Doctrine::loadModels($doctrineConfig['models_path'], Doctrine::MODEL_LOADING_CONSERVATIVE);
$conn = Doctrine_Manager::connection($doctrineConfig['dsn'], 'doctrine');

// Doctrine_Core::generateModelsFromDb(APPLICATION_PATH.'/models', array('doctrine'), array('generateTableClasses' => true));
$conn->setAttribute(Doctrine::ATTR_USE_NATIVE_ENUM, true);

return $conn;
}


Odkomentowuje sobie tylko linijkę Doctrine::Core, jeśli wprowadziłem jakieś zmiany w bazie, odświeżam stronę i wtedy Doctrine sam generuje sobie modele, warunek jeden, że baza musi być w INNODB i poustawiane klucze obce. Normalnie ta linijka jest zakomentowana cały czas.Ten post został edytowany przez Autora dnia 27.05.13 o godzinie 13:15
Maciej Filipiak

Maciej Filipiak właściciel, VizMedia

Temat: Ja chcę czysty SQL!

Krzysztof N.:
Zauważcie, że uzyskujemy możliwość przenoszenia aplikacji na inne bazy danych bez konieczności przepisywania kodu, bo serwer nie rozumie składni.

To jest mrzonka.
Jak często przenosisz system między różnymi motorami bazy danych ?
Mi się zdarzyło raz - z mysql na postgresql - i wcale nie wystarczyło zmienić PDO w ini.

Również stosuję ORM'y, ale z niesmakiem.
Czuję sens ich istnienia (np. bindowanie z kontrolkami) - ale mimo wszystko nie jestem przekonany.
Wcale nie trudniej zrobić wszystko "na piechotę".
A w efekcie kodu mniej i jest czytelniejszy.
Krzysztof N.

Krzysztof N. CEO. Aplikacje
internetowe i
mobilne. Symfony,
Zend.

Temat: Ja chcę czysty SQL!

Maciej F.:
To jest mrzonka.
Jak często przenosisz system między różnymi motorami bazy danych ?
Mi się zdarzyło raz - z mysql na postgresql - i wcale nie wystarczyło zmienić PDO w ini.
Widocznie aplikacja tak została napisana. Pamiętaj, że samo wykorzystanie frameworka lub ORMu nie oznacza poprawnie stworzonej aplikacji.
Maciej F.:
Również stosuję ORM'y, ale z niesmakiem.
Czuję sens ich istnienia (np. bindowanie z kontrolkami) - ale mimo wszystko nie jestem przekonany.
Wcale nie trudniej zrobić wszystko "na piechotę".
A w efekcie kodu mniej i jest czytelniejszy.
Maciej, każdy ma prawo do własnego zdania i może robić tak jak jemu wygodniej i efektywniej.
Maciej Filipiak

Maciej Filipiak właściciel, VizMedia

Temat: Ja chcę czysty SQL!

Gdyby jeszcze ORM'y nadążały za możliwościami SQL'a ... nie było by frustracji przy ich stosowaniu.
Łukasz Mordawski

Łukasz Mordawski Programista PHP

Temat: Ja chcę czysty SQL!

Krzysztof N.:
Zauważcie, że uzyskujemy możliwość przenoszenia aplikacji na inne bazy danych bez konieczności przepisywania kodu, bo serwer nie rozumie składni.

To jest mrzonka.
Jak często przenosisz system między różnymi motorami bazy danych ?
Mi się zdarzyło raz - z mysql na postgresql - i wcale nie wystarczyło zmienić PDO w ini.
>

O ile z pierwszą częścią wypowiedzi się zgodze, jeszcze nie zdarzyło mi się migrować aplikacji na inny silnik bazy danych, o tyle z drugą - nie. Bo PDO to nie ORM. z PDO robisz to samo co z funkcjami mysql_* (i odpowiednikami dla innych baz), tylko w obiektowy sposób. Używając np. Doctrine, owszem, wystarczyłoby podmienić adapter.
Również stosuję ORM'y, ale z niesmakiem.
Czuję sens ich istnienia (np. bindowanie z kontrolkami) - ale mimo wszystko nie jestem przekonany.
Wcale nie trudniej zrobić wszystko "na piechotę".
A w efekcie kodu mniej i jest czytelniejszy.

Może i mniej, ale ty musisz napisać więcej. Najgorsza część projektu w Zend'zie to dla mnie pisanie modeli i mapperów, gdzie mam x klas, których nie połączę dziedziczeniem, a do których kod będzie wyglądał bardzo podobnie. Doctrine większość rzeczy, które tam robię na piechotę, robi za mnie.
Łukasz C.

Łukasz C. Senior Technical
Architect

Temat: Ja chcę czysty SQL!

Proponuje podejscie typu SQL Query Builder ktory to umozliwia obiektowe skladanie zapytan bez meczenia sie z laczeniem stringow, umozliwia to robienie obiektowych zapytan ktore moga byc zwracane przez funkcje, modyfikowane itp.

Doctrine posiada query builder ale domyslnie bazuje on na DQL ktory wymaga mapowania modeli,

mozesz sprobowac tego wynalazku, ktory operuje na golym SQL:

https://github.com/cepa/php_commons-4/tree/master/src/C...

przyklad uzycia:

$collection = $conn->createQuery()
->select('*')
->from('identity')
->orderBy('first_name')
->execute()
->fetchCollection();
foreach ($collection as $entity) {
echo "{$entity->first_name} {$entity->last_name}\n";
}


https://github.com/cepa/php_commons-4/blob/master/examp...
https://github.com/cepa/php_commons-4/blob/master/examp...
Dominik Marczuk

Dominik Marczuk Remote Team Lead w
Sonalake

Temat: Ja chcę czysty SQL!

Daniel K.:
Cześć!

Mam za sobą już trochę początków z Zendem i właśnie doszedłem do wniosku, że nie chcę już mieć do czynienia z Db_Table, bo więcej z tym problemów niż pożytku, zwłaszcza gdy większość operacji wykonuję na bazie, a Db_Table najzwyczajniej nie radzi sobie z takimi skomplikowanymi zapytaniami i do tego jest nieczytelne.

Podpowie mi ktoś, jak używać czystego SQLa? Bo naczytałem się masy różnych dziwnych tutoriali i poradników, i co który gada co innego.

W modelu:

return $this->_db->fetchRow("SELECT * FROM users WHERE id =  :id", array("id" => 1));


Poza modelem:

$model = new Model_User();
$user = $model->getAdapter()->fetchRow("SELECT * FROM users WHERE id = :id", array("id" => 1));
Ten post został edytowany przez Autora dnia 05.06.13 o godzinie 09:29
Tomasz Kuter

Tomasz Kuter Web Application
Developer

Temat: Ja chcę czysty SQL!

Daniel K.:
Myślałem o Doctrine, ale ten z kolei jest już kombajnem, który wcina też trochę zasobów, no i wciąż jest to sprzeczne z moim założeniem o inteligencji takich systemów, o czym przekonałem się chwilę temu.

Zdążyłem już wyrzucić problemowy kod dla DbTable, być może błąd był po mojej stronie, nie wiem, dla człowieka, który widzi SQL, pracuje na nim kilka lat i 'widzi' co mu zwraca i w jakiej postaci jest to po prostu zbędny bajer.

No i przy obecnych doświadczeniach z tym wynalazkiem jakoś nie mogę wyobrazić sobie zapisania takiego zapytania - https://ideone.com/Ktb81W - przy użyciu ORMa.

Jeśli chodzi o to: http://framework.zend.com/manual/1.12/en/zend.db.state...
Doszedłem do wniosku, że najprościej będzie zrobić swój model i w nim prostacką funkcję do wysyłania zapytań.
Jak mniemam $db to adapter do bazy. Jak mogę go pobrać w modelu?

A application.ini mam skonfigurowany:
resources.db.adapter = "pdo_mysql"

W kontrolerach brałem po prostu $this->bootstrap, ale przecież chyba nie powinienem dziedziczyć modelu po Zend_Controller

Zastanawiam się, czy nie dałoby się przenieść tego do funkcji przechowywanej po stronie bazy danych?
Wtedy Zend_Db by spokojnie dał radę...
Tomasz Kuter

Tomasz Kuter Web Application
Developer

Temat: Ja chcę czysty SQL!

Cześć!
A propos skomplikowanych zapytań... co powiesz na to:


$oSelect1 = $this->select()
->from(array('o' => $this->_name), array(
'o.i_id', 'o.s_name', 'o.s_tags', 'o.s_place',
'o.i_region_id', 'o.i_district_id',
'o.s_gps_coords'
))
->columns(array(
'i_location_type' => new Zend_Db_Expr(Objects_Model_Poi_Row::LOCATION_TYPE_SINGLE),
's_availability' => new Zend_Db_Expr('NULL'),
'i_type' => new Zend_Db_Expr(self::OBJECT_TYPE_NORMAL),
))
->setIntegrityCheck(false)
->joinLeft(array('s1' => 'erp_packages_services_accommodations'), 's1.i_object_id = o.i_id AND s1.s_deleted_at IS NULL',
array(
's1.i_id as i_accommodation_id', 's1.s_name as s_accommodation_name', 's1.i_out_of_season_availability',
's1.i_other_localization as i_accommodation_other_localization', 's1.s_gps_coords as s_accommodation_gps_coords'
)
)
->joinLeft(array('s2' => 'erp_packages_services_catering'), 's2.i_object_id = o.i_id AND s2.s_deleted_at IS NULL',
array('s2.i_id as i_catering_id', 's2.s_name as s_catering_name')
)
->joinLeft(array('s4' => 'erp_packages_services_attractions'), 's4.i_object_id = o.i_id AND s4.s_deleted_at IS NULL' . $s_where_s4,
array(
's4.i_id as i_attraction_id', 's4.s_name as s_attraction_name',
's4.i_other_location as i_attraction_other_location', 's4.s_gps_coords as s_attraction_gps_coords', 's4.i_location_type as i_attraction_location_type'
)
)
->joinLeft(array('p2o' => 'erp_pictures2objects'), 'p2o.i_object_id = o.i_id AND p2o.i_main = 1',
array('p2o.i_picture_id')
)
->joinLeft(array('p' => 'erp_pictures'), 'p.i_id = p2o.i_picture_id',
array('p.s_extension as s_picture_extension')
)
;

if ($params['s_starting_at'] !== '' || $params['s_ending_at'] !== '') {
$oSelect1->joinLeft(array('s1s' => 'erp_packages_services_accommodations_seasons'), 's1s.i_accommodation_id = s1.i_id AND s1s.s_deleted_at IS NULL' . $s_where_s1s,
array('s1s.i_id as i_season_id')
);
}

$oSelect1->where('s1.i_id IS NOT NULL OR s2.i_id IS NOT NULL OR s4.i_id IS NOT NULL');

if ($params['s_text'] !== '') {
$oSelect1->where("LOWER(o.s_name) LIKE LOWER('%{$params['s_text']}%') OR LOWER(o.s_tags) LIKE LOWER('%{$params['s_text']}%')");
}

if ($params['i_accommodation'] !== '0') {
$oSelect1->where('s1.i_id IS NOT NULL');
}
if ($params['i_catering'] !== '0') {
$oSelect1->where('s2.i_id IS NOT NULL');
}
if ($params['i_attraction'] !== '0') {
$oSelect1->where('s4.i_id IS NOT NULL');
}

if ($params['s_place'] !== '') {
$oSelect1->where('LOWER(o.s_place) LIKE LOWER(?)', $params['s_place']);
}
if ($params['i_land_id'] !== '') {
$oSelect1->where('o.i_land_id = ?', $params['i_land_id']);
}
if ($params['i_region_id'] !== '') {
$oSelect1->where('o.i_region_id = ?', $params['i_region_id']);
}
if ($params['i_district_id'] !== '') {
$oSelect1->where('o.i_district_id= ?', $params['i_district_id']);
}

$firephp->info($oSelect1->__toString(), 'sql');

$oPoiModel = new Objects_Model_Poi();
$oSelect2 = $oPoiModel->findServices($params);

if (!$params['i_poi'] && (!$params['i_accommodation'] && !$params['i_catering'] && !$params['i_attraction'])) {
// przeszukaj usługi i obiekty okołoturystyczne
$oUnionSelect = $this->select()->union(array($oSelect1, $oSelect2), Zend_Db_Select::SQL_UNION_ALL);
$firephp->info($oUnionSelect->__toString(), 'sql');
$aRowset = $this->fetchAll($oUnionSelect)->toArray();
} else if ($params['i_accommodation'] || $params['i_catering'] || $params['i_attraction']) {
// przeszukaj tylko usługi
$aRowset = $this->fetchAll($oSelect1)->toArray();
} else if ($params['i_poi']) {
// przeszukaj tylko obiekty okołoturystyczne
$aRowset = $this->fetchAll($oSelect2)->toArray();
}


W skrócie: dwa selecty: $oSelect1 i $oSelect2, a w razie potrzeby tworzona jest z nich unia

Temat: Ja chcę czysty SQL!

Daniel K.:
Cześć!

Mam za sobą już trochę początków z Zendem i właśnie doszedłem do wniosku, że nie chcę już mieć do czynienia z Db_Table, bo więcej z tym problemów niż pożytku, zwłaszcza gdy większość operacji wykonuję na bazie, a Db_Table najzwyczajniej nie radzi sobie z takimi skomplikowanymi zapytaniami i do tego jest nieczytelne.

Podpowie mi ktoś, jak używać czystego SQLa? Bo naczytałem się masy różnych dziwnych tutoriali i poradników, i co który gada co innego.

Nie zrozum mnie źle, ale Twoje problemy z Zend_Db_Table świadczą o tym, że jesteś nowicjuszem.
Moja rada jest taka, abyś porzucił Zenda 1 i przesiadł się na Zenda 2 bo niebawem Zend 1 stanie się archaizmem.
Jarosław Grzelak

Jarosław Grzelak Software Engineer,
StepStone Services
Sp. z o.o.

Temat: Ja chcę czysty SQL!

Łukasz C.:

Moja rada jest taka, abyś porzucił Zenda 1 i przesiadł się na Zenda 2 bo niebawem Zend 1 stanie się archaizmem.

To sobie długo poczekamy. Bo jak widzę tego nowego Zend 2 to mnie krew zalewa.

Temat: Ja chcę czysty SQL!

Mnie krew zalewa jak widzę takie zapiski jak poniżej:
[quote]$oSelect1 = $this->select()
->from(array('o' => $this->_name), array(
'o.i_id', 'o.s_name', 'o.s_tags', 'o.s_place',
'o.i_region_id', 'o.i_district_id',
'o.s_gps_coords'
))
->columns(array(
'i_location_type' => new Zend_Db_Expr(Objects_Model_Poi_Row::LOCATION_TYPE_SINGLE),
's_availability' => new Zend_Db_Expr('NULL'),
'i_type' => new Zend_Db_Expr(self::OBJECT_TYPE_NORMAL),
))
->setIntegrityCheck(false)
->joinLeft(array('s1' => 'erp_packages_services_accommodations'), 's1.i_object_id = o.i_id AND s1.s_deleted_at IS NULL',
array(
's1.i_id as i_accommodation_id', 's1.s_name as s_accommodation_name', 's1.i_out_of_season_availability',
's1.i_other_localization as i_accommodation_other_localization', 's1.s_gps_coords as s_accommodation_gps_coords'
)
)
->joinLeft(array('s2' => 'erp_packages_services_catering'), 's2.i_object_id = o.i_id AND s2.s_deleted_at IS NULL',
array('s2.i_id as i_catering_id', 's2.s_name as s_catering_name')
)
->joinLeft(array('s4' => 'erp_packages_services_attractions'), 's4.i_object_id = o.i_id AND s4.s_deleted_at IS NULL' . $s_where_s4,
array(
's4.i_id as i_attraction_id', 's4.s_name as s_attraction_name',
's4.i_other_location as i_attraction_other_location', 's4.s_gps_coords as s_attraction_gps_coords', 's4.i_location_type as i_attraction_location_type'
)
)
->joinLeft(array('p2o' => 'erp_pictures2objects'), 'p2o.i_object_id = o.i_id AND p2o.i_main = 1',
array('p2o.i_picture_id')
)
->joinLeft(array('p' => 'erp_pictures'), 'p.i_id = p2o.i_picture_id',
array('p.s_extension as s_picture_extension')
)
;

if ($params['s_starting_at'] !== '' || $params['s_ending_at'] !== '') {
$oSelect1->joinLeft(array('s1s' => 'erp_packages_services_accommodations_seasons'), 's1s.i_accommodation_id = s1.i_id AND s1s.s_deleted_at IS NULL' . $s_where_s1s,
array('s1s.i_id as i_season_id')
);
}

$oSelect1->where('s1.i_id IS NOT NULL OR s2.i_id IS NOT NULL OR s4.i_id IS NOT NULL');

if ($params['s_text'] !== '') {
$oSelect1->where("LOWER(o.s_name) LIKE LOWER('%{$params['s_text']}%') OR LOWER(o.s_tags) LIKE LOWER('%{$params['s_text']}%')");
}

if ($params['i_accommodation'] !== '0') {
$oSelect1->where('s1.i_id IS NOT NULL');
}
if ($params['i_catering'] !== '0') {
$oSelect1->where('s2.i_id IS NOT NULL');
}
if ($params['i_attraction'] !== '0') {
$oSelect1->where('s4.i_id IS NOT NULL');
}

if ($params['s_place'] !== '') {
$oSelect1->where('LOWER(o.s_place) LIKE LOWER(?)', $params['s_place']);
}
if ($params['i_land_id'] !== '') {
$oSelect1->where('o.i_land_id = ?', $params['i_land_id']);
}
if ($params['i_region_id'] !== '') {
$oSelect1->where('o.i_region_id = ?', $params['i_region_id']);
}
if ($params['i_district_id'] !== '') {
$oSelect1->where('o.i_district_id= ?', $params['i_district_id']);
}

$firephp->info($oSelect1->__toString(), 'sql');

$oPoiModel = new Objects_Model_Poi();
$oSelect2 = $oPoiModel->findServices($params);

if (!$params['i_poi'] && (!$params['i_accommodation'] && !$params['i_catering'] && !$params['i_attraction'])) {
// przeszukaj usługi i obiekty okołoturystyczne
$oUnionSelect = $this->select()->union(array($oSelect1, $oSelect2), Zend_Db_Select::SQL_UNION_ALL);
$firephp->info($oUnionSelect->__toString(), 'sql');
$aRowset = $this->fetchAll($oUnionSelect)->toArray();
} else if ($params['i_accommodation'] || $params['i_catering'] || $params['i_attraction']) {
// przeszukaj tylko usługi
$aRowset = $this->fetchAll($oSelect1)->toArray();
} else if ($params['i_poi']) {
// przeszukaj tylko obiekty okołoturystyczne
$aRowset = $this->fetchAll($oSelect2)->toArray();
}[/quote]


Powyższe zapytanie jest niczym innym jak antywzorcem. Jest nieczytelne i posiada błędy.
Takie rzeczy robi się poprzez widoki ( w końcu do czegoś one są).

Następna dyskusja:

Stawianie www na innym serw...




Wyślij zaproszenie do