Select complexo? View nele
Posted on September 20, 2007, under Symfony.
No início do projeto que estamos trabalhando, a equipe de desenvolvimento cogitou a utilização do framework Cake, além de tantas outras opções, acabamos por escolher Symfony e PostgreSQL.Mas no período de escolha, acabamos por testar uma solução, digamos atípica, no Cake. O sistema no qual trabalhamos é uma nova versão de um sistema que já existia anteriormente, e precisávamos reaproveitar sua base de dados, foi ai que encontramos uma série de limitações, principalmente com a nomenclatura de tabelas e campos. Nada que não fosse possível contornar com configurações no Cake, mas isso não era uma boa opção visto que iríamos perder a maiorias das facilidades do Cake.
Uma das tentativas de reutilizar a base de dados, sem perder as vantagens, foi criar uma outra base de dados no mesmo servidor, e algumas views, ligando uma base de dados a outra. Você pode estar se perguntando agora porque simplesmente não refizemos a base? Porque precisávamos manter o sistema antigo funcionando, enquanto criávamos um novo sistema.
O Cake se comporta bem com uso de views no lugar de tabelas, isso acontece porque o mysql lista views como tabelas, e para o Cake criar models a partir de tabelas ou views não fazia a menor diferença. Mas no fim descobrimos que isso era muito lento (views de um banco para outro), e que as views não iriam suportar a quantidade de informações com que o sistema trabalha.
Mais tarde quando estávamos implementando o novo sistema, esbarramos em uma serie de selects complexas, afinal para quem já trabalhou com Symfony sabe com é cansativo elaborar uma select com uso do criteria, principalmente se a select for composta de algumas joins e qualquer outra condição não convencional é melhor implementar a select diretamente do que tentar implementar utilizando criteria. Nós enxergamos inicialmente duas soluções para este caso.
A primeira foi a já citada elaboração de selects diretamente no código dos models, funciona bem, mas é muito dispendioso o processo de analisar o dados de retorno sem falar no fato que o código do model se torna mais difícil de manter e muito poluído.
A segunda opção, foi utilizar store procedures, além de uma melhora de performance em relação as selects “diretas”, o código do model fica levemente poluído, mas ainda sim esta solução e dispendiosa no tratamento dos retornos.
Uma terceira solução partiu dos testes feitos com Cake, o uso de views, elas são mais fáceis de escrever do que uma função, e pode, digamos “enganar” o propel, e fingir se uma tabela, o que tornaria o código dos models muito mais limpo e na maioria dos casos sem a necessidade de qualquer tipo de alteração.
Tudo bem, até ai, a idéia é boa, mas funciona? A questão é que o PostgreSQL trata views como views e tabelas como tabelas, ou seja, são objetos, mas objetos de tipos totalmente diferentes. Isso se torna um problema quando se utiliza o propel-build-schema, o que é o nosso caso. De outra forma para quem prefere atualizar a base com o uso do schema, isso não é um problema, basta alterar o seu schema agindo como se a view fosse uma tabela como outra qualquer que o resultado vai ser joinha
Para aqueles que como nós, prefere manter o banco de dados através de ferramentas administrativas como phpPgAdmin ou pgAdmin III ou ainda com uso de uma ferramenta de modelagem, há uma solução. Analisando o driver de PostgreSQL do propel, encontrei a solução, gastava apenas uma alteração no arquivo que captura as informação da base, para que a coisa funcionasse. Vamos lá:
Edite o arquivo vendor/creole/drivers/pgsql/metadata/PgSQLDatabaseInfo.php disponível na sua pasta do symfony (ubuntu: /usr/share/php/symfony). E mude a seguinte linha:
$sql = “SELECT oid, relname FROM pg_class WHERE relkind = ‘r’
para:
$sql = “SELECT oid, relname FROM pg_class WHERE ( relkind = ‘r’ OR relkind = ‘v’ )
Esta select é responsável por buscar no catálogo do PostgreSQL pelos objetos da base, mas está definida para buscar apenas objetos do tipo tabela, o que impede o propel de gerar o schema para views.
Com esta alteração o propel passa a processar as views disponíveis no banco. Isto parece muito simples, e realmente é simples assim. Existe um pequeno porém neste método: uma view não tem informações sobre relacionamento com outras tabelas, o que dificulta na hora de buscar models relacionados.
3 Replies to "Select complexo? View nele"
dynaum on November 21, 2007
Muito bom esse POST!!
Um amigo meu me falou que era possivel visões no symfony e não estava conseguindo criar os objetos para ela, mas agora tudo funcionando como uma maravilha!!!
Continue postando coisas sobre symfony aí brother!!
hauheauheauhe…
Select complexo? View nele « Eu vou pra NASA on May 14, 2008
[...] post info Por nuxlli Categorias: Symfony Este post mudou de casa: http://www.nuxlli.com.br/2007/09/20/select-complexo-view-nele/ [...]

Rudy on September 20, 2007
Parabéns pelo artigo! Como o symfony é relativamente novo encontra-se pouca coisa sobre o assunto, principalmente a experiência de quem já passou por uma dificuldade e compartilha com outros usuários.
Viva a Liberdade!