Manejar multiples schemas con postgres en cakephp 1.2
Uno de los problemas mas grandes que conseguimos en el trabajo para trabajar con cake, es que al parecer, aun no maneja de manera idel multiples schemas, y digo de manera ideal porque si los toma en cuenta, pero es muy limitante que solo te permita manejar un schema por conexión.
Esto era un gran problema para nosotros, porque los sistemas son gigantes y la utilización de schemas nos ayuda muchisimo, asi que teniamos que conseguir la manera de que funcionara con multiples schemas, sino hubiesemos perdido todo el tiempo que hemos pasado migrando a un framework.
El principal problema radica en que cake te permite hacer multiples conexiones a la BD, y por conexión especificar un schema, lo que yo hice fue modificar cake para que adminitira multiples schemas por conexión, para esto vamos a modificar un solo archivo llamado ‘dbo_postgres.php’ y se encuentra en
cake/cake/libs/model/datasources/dbo/dbo_postgres.php
En la función connect vamos a agregar estas lineas, despues de esta linea $this->connected = true; y antes de esta (reemplaza lo que sea que este en el medio) $this->_execute(”SET search_path TO ” . $schemas) (< -- esta ultima linea deben incluirla, sustituyendo la original);
if(is_array($config['schema'])){
$sci = count($config['schema']);
$schemas = '';
for($i=0; $i< $sci; $i++){
if($i+1 == $sci)
$schemas = $schemas . $config['schema'][$i];
else
$schemas = $schemas . $config['schema'][$i]. " , ";
}
}
else{ $schemas = $config['schema'];
}
Un poco mas abajo en ese mismo archivo modificamos la función ‘listSources()’ colocando luego de estas lineas
if ($cache != null) {
return $cache;
}
y antes de estas
$result = $this->fetchAll($sql);
este pedazo de codigo
if(is_array($this->config['schema'])){
$sci = count($this->config['schema']);
$schemas = '';
for($i=0; $i< $sci; $i++){
if($i+1 == $sci)
$schemas = $schemas . "table_schema = '" .$this->config[’schema’][$i].”‘”;
else
$schemas = $schemas . “table_schema = ‘”.$this->config[’schema’][$i]. “‘ OR “;
}
$schema = $schemas;
$sql = “SELECT table_name as name FROM INFORMATION_SCHEMA.tables WHERE {$schema};”;
}else{
$schema = $this->config[’schema’];
$sql = “SELECT table_name as name FROM INFORMATION_SCHEMA.tables WHERE table_schema = ‘{$schema}’;”;
}
Y listo! Ahora para manejar los multiples esquemas solo tenemos que usar la variable schema en la configuración de la base de datos como un arreglo asi
var $default = array(
'driver' => 'postgres',
'persistent' => false,
'host' => 'localhost',
'port' => '5432',
'login' => 'postgres',
'password' => 'postgres',
'database' => 'cake',
'schema' => array( 'public', 'transporte'),
'prefix' => '',
'encoding' => ''
);
Por ahora esta solución no me ha dado ningun problema, cualquier duda o problema que tengan pregunten en los comentarios, igual yo lo estoy usando y cualquier problema que se presente tengo que arreglarlo xD xD

¡Hola! Gracias por publicar la información, ha sido de utilidad. ¿Has pensado contactar a los desarrolladores en #cakephp y/o enviarles un patch? Incluso si hubiese algún problema hasta ahora no detectado, seguramente tener esta funcionalidad en el _core_ será de utilidad para muchos, e incluso, como en la mayoría de los proyectos de software libre, terminemos sorprendiéndonos de lo rápido que otros mejoran nuestras ideas
Juan - Marzo 5th, 2008 at 2:26 pm
Que bueno que te ha funcionado, a mi me ahorro muchos dolores de cabeza.
y bueno la verdad es que no he abierto un ticket, hay varios ya abiertos sobre el tema, hay un hilo en el grupo de google donde plantee el problema y luego la solución, que vale decir que no funciona con tablas del mismo nombre en distintos esquemas, pero no creo que un tickect ayude mucho, ademas de que probablemente no sea la mejor solución, igual no cre que duren mucho antes de liberar la 1.2 estable que seguro ya resuelve este problema. mientras tanto pues esta este parche jeje
Saludos! y gracias por comentar ^^
prozac - Marzo 5th, 2008 at 4:35 pm
Hola!.. precisamente me encuentro con el problema de los schemas multiples. CakePHP parece haber sido diseñado con espacios simples de bases de datos, muy a la MySQL, y el soporto para postgres es relativamente básico. Este asunto de los schemas múltiples es de gran utilidad.
Sería posible que publicaras en esta entrada un patch? de esta manera sería mas facil aplicar los cambios al archivo.
Gracias de antemano.
Hlecuanda - Mayo 13th, 2008 at 2:10 pm
Aquí dejo el Patch para quien guste aplicarlo. Hice algunas correcciones con el unicode que wordpress amablemente pega x todos lados en el código, y que hacen casi imposible el cutandpaste
Luego escribiré un post en mi blog al respecto. Si quieres enviar el parche a los desarrolladores de cake, bienvenido. Hay algunas otras modificaciones que me gustaría hacer, sin embargo por la premura me es imposible en estos momentos.
Saludos y gracias mil
==== //bluestar2/cake/libs/model/datasources/dbo/dbo_postgres.php#1 - /usr/local/www/cake2/cake/libs/model/datasources/dbo/dbo_postgres.php ====
--- dbo_postgres.php.orig Tue May 13 14:30:34 2008
+++ dbo_postgres.php Tue May 13 14:30:34 2008
@@ -91,7 +91,26 @@
if ($this->connection) {
$this->connected = true;
- $this->_execute("SET search_path TO " . $config['schema']);
+
+ // Multiple Schema Support
+ // From http://www.prothotype.com/blog/archives/609/manejar-multiples-schemas-con-postgres-en-cakephp-12/
+
+ if(is_array($config[’schema’])){
+ $sci = count($config[’schema’]);
+ $schemas = ”;
+ for($i=0; $i_execute(”SET search_path TO ” . $schemas);
+
} else {
$this->connected = false;
}
@@ -134,6 +153,22 @@
return $cache;
}
+ if(is_array($this->config[’schema’])){
+ $sci = count($this->config[’schema’]);
+ $schemas = ”;
+ for($i=0; $iconfig[’schema’][$i].”‘”;
+ else
+ $schemas = $schemas . “table_schema = ‘”.$this->config[’schema’][$i]. “‘ OR ‘” ;
+ }
+ $schema = $schemas;
+ $sql = “SELECT table_name as name FROM INFORMATION_SCHEMA.tables WHERE {$schema};”;
+ } else {
+ $schema = $this->config[’schema’];
+ $sql = “SELECT table_name as name FROM INFORMATION_SCHEMA.tables WHERE table_schema = ‘{$schema}’;”;
+ }
+
$schema = $this->config[’schema’];
$sql = “SELECT table_name as name FROM INFORMATION_SCHEMA.tables WHERE table_schema = ‘{$schema}’;”;
$result = $this->fetchAll($sql);
@@ -590,4 +625,4 @@
}
}
-?>
\ No newline at end of file
+?>
Para aplicarlo simplemente copia el código anterior a un archivo llamado schemas.patch en el mismo directorio donde se encuentre dbo_postgres.php y ejecuta
patch < schemas.patch
Si estás en windows… lo siento =P aplica para patch POSIX. (*BSD, GNU/Linux)
Hlecuanda - Mayo 13th, 2008 at 6:10 pm
que buen aporte Hlecuanda, ahorita ando un poco despegado del desarrollo de aplicaciones en cake porque cambie de compañia y ahora ando trabajando con Java pero sigo haciendo algunas cositas con cake pero mas sencillas.
PD: si seria bueno es poner de una el archivo ‘parcheado’ para descarga jejeje
prozac - Mayo 13th, 2008 at 6:35 pm