Bonjour à tous,

J'utilise une base de données Oracle avec CakePHP avec la configuration suivante :

public $default = array(
    'datasource' => 'Database/Oracle',
    'persistent' => false,
    'login' => 'my_user_web',
    'password' => '*****',
    'database' => 'my_server:1521/MY_SID',
    'prefix' => '',
    'encoding' => 'utf8',
);

De cette manière, mes utilisateurs sont crées :

create user my_user_schema
        identified by "********"
        default tablespace TBS_DATA
        quota unlimited on TBS_DATA
        quota unlimited on TBS_INDEX
        account lock
;

create role web_role 
;

create user my_user_web
        identified by "********"
        default tablespace TBS_DATA
;

grant web_role 
    to my_user_web ;

grant select 
    on 
        my_user_schema.posts 
    to
        my_user_web
;

Mes tables (ex : posts, comments, ...) sont préfixées par l'utilisateur my_user_schema (ex: select * from my_user_schema.posts) , qui est le propriétaire de ce schéma.

Mon problème est :
Quand je veux lister mes posts dans mon PostsController avec : $posts = $this->Post->find('all'), il m'affiche l'exception suivante :

Error: Table posts for model Post was not found in datasource default.

Merci d'avance.

14 réponses


azenakhi
Auteur
Réponse acceptée

Bonjour,

J'ai trouvé la solution après une longue période de tests et je souhaite partager avec vous cette information.

Pour que CakePHP voit le nom de la table préfixées par my_user_schema (propriétaire du schéma), on crée un synonym avec la ligne de commande suivante :

En tant que sysdba (admin database)
SQL> grant create synonym to my_user_web;

En tant que my_user_web
SQL> create synonym posts for my_user_schema.posts;

Puis, on modifie légèrement la classe lib/Cake/Model/Datasoure/Database/Oracle.php comme suit :

user_tables -> all_tables
user_tab_columns -> all_tab_columns
user_constraints -> all_constraints

Alors je n'ai aucune idée de comment fonctionne oracle mais tu ne devrais pas mettre my_user_schema. en prefix ?

azenakhi
Auteur

Merci beaucoup pour ta réponse,

Sous Oracle ça fonctionne comme ça. Surtout en production, on crée un utilisateur qui peut juste se connecter à une base et pour lancer des requêtes, on est obiligé de les préfixer par le propriétaire du schéma. Sinon, on aura le message "Table ou vue inexistante".

Avec PDO , ça fonctionne : $stmt = $db->prepare('select * from my_user_schema.posts');

Je suis vraiment déçu par cette surprise, car ce framework je l'ai proposé à mon entreprise.

Tu peux changer le prefix à la volée par exemple dans l'AppModel pour faire en sorte de l'adapter suivant les cas je pense

azenakhi
Auteur

Dans mon cas, my_user_schema c'est le propriétaire du schéma, ce n'est pas un préfix. Le préfix a un autre avanatge, ça permet de gérer un ou plusieurs models de données identiques dans une même base de données (ex: app1_posts, app2_posts).

Bonsoir Joyeux Noel.Bon il faut d'abord spécifié la version de cakephp et la version de ton oracle.Ensuite tu devrait t'assurer d'avoir bien créé le model Post .Montre moi ton controller et ton model.Voici quelque chose que j'ai trouvé

<?php
class DATABASE_CONFIG {

  public $default = array(
    'datasource' => 'Database/Oracle',
    'driver' => 'oracle',
    'connect' => 'oci_pconnect',
    'persistent' => false,
    'host' => 'localhost',
    'login' => 'SYSTEM',
    'password' => 'Admin01',
    'database' => 'localhost:1521/orcl.64.126.18',
    'prefix' => '',
    'schema' => 'SYSTEM'
    //'encoding' => 'utf8',
  );
}

ou
pour Cake PHP il faut absolument mettre le nom équivalent au champs SERVICE_NAME du fichier tnsnames.ora et pour la connexion a la bdd il faut utiliser orcl.64.126.18.
Et surtout je t'interdis de désespérer XD.Cakephp peut bien s'adapter a Oracle.On va trouvé la solution tout les deux ensemble

azenakhi
Auteur

Bonsoir,
Bonne fête de Noël et je vous remercie tous du temps que vous m'avez consacré pour résoudre ce problème.

Version Oracle : 11g.
Version CakePHP : 2.6.0.

Controller :

<?php
class PostsController extends AppController {
    public function index() {
        $posts = $this->Post->find('all');
        var_dump($posts);  
    }
}

Model :

<?php
class Post extends AppModel {

}

oops .Apparement a partir de la version 2.0 cakephp ne prend plus en charge Oracle,je te conseille d'utiliser les version en dessous par ex le 1.3 et Réessay pour voir

Ou soit tu peut sacrifier les joies de l'utilisation des models a pleine puissance de cakephp en utilisant oci_parce de php pour directement faire les requêtes de facon brutes comme en php ou appelé la procédure PL-SQL .Pour la documentation
http://php.net/manual/en//function.oci-parse.php
Pour la version cakephp 2.0 utilise les indications sur ce site que je viens de trouver

https://bitbucket.org/odin88/cakephp-2.0-oracle/src

azenakhi
Auteur

Je n'ai pas crée des choses spécifiques (bruttes) à Oracle. Ma table contient seulement deux champs (id et name). Mon example fonctionne correctement. Mais, quand je commence à gérer les utilisateurs avec des rôles, c'est là que la classe Oracle.php de CakePHP n'arrive pas à voir les tables dans la base de données.

A l'occasion, pourquoi CakePHP n'intègre pas Oracle depuis sa version 2.0 ?

Pour mon exemple, j'ai utilisé la classe Oracle.php de la version 1.3.

Pour le coup je ne sais pas la raison qui les a poussé a ne pas integrer oracle a partir de la version 2.0 lol .Mais pour la gestion des Roles d'utilisateurs,tu peux me donner plus de détails pour voir comment tu la gère?

azenakhi
Auteur

Merci de reprendre mon premier message.

Deja je suis content que tu es trouvé la solution et en plus de l'avoir partagé.Donc ca voudrait dire que tu es toujours sur le 2.4?

azenakhi
Auteur

J'utilise la version 2.6.0 de CakePHP. Et pour la datasource Oracle, j'utilise une classe qui est dans ce lien : https://github.com/kdyouri/cakephp-2.x_oracle-driver/blob/master/Oracle.php.