Page 1 sur 1

[Symfony] Gérer une vue dans le schéma

Posté : 21 févr. 2009, 04:18
par Calimero
Contexte : symfony 1.0, propel 1.3, MySQL 5.0.75

Je construis actuellement une application web avec symfony qui fait usage de tableaux de synthèse (requêtes lourdes avec GROUP BY) que je souhaite pouvoir gérer dans des interfaces d'admin générées, tout comme on le fait classiquement avec des tables ordinaires.

Pour ce faire j'utilise donc des vues. Il suffit de les déclarer dans le schéma (en imitant une table de même structure), de générer la classe métier correspondante, et hop : symfony sait les utiliser comme des tables standard. Tout ça marche bien et c'est génial, SAUF QUE :

- Comment je peux expliquer à symfony qu'il ne doit pas toucher (ni détruire, ni créer de table) à ces vues lorsque je lui demande de générer le code SQL de création de la base de données ? Y aurait-il un paramètre magique qui m'échappe ?

- Réciproquement, comment faire comprendre à symfony que la vue n'est pas traitable pour une opération dump-data ou load-data ?

- Mieux encore (mais bon là, je rêve... non ?), pourrais-je créer directement les vues (avec les tables) à partir du schéma en même temps que les tables ?

Vos avis et suggestions sont les bienvenus :)

Re: [Symfony] Gérer une vue dans le schéma

Posté : 21 févr. 2009, 19:35
par naholyr
Attention à bien situer, il s'agit d'une question liée à l'ORM choisi (dont Propel ou Doctrine à priori) et pas directement à Symfony. Donc je vais te répondre pour Propel.


Il faut :
- Créer ta vue dans ta base de données
- Ajouter la table correspondante dans ton schema.yml, et spécifier readOnly:yes dans les _attributes.
- Générer les classes de ton modèle, la classe correspondante n'aura pas les méthodes save & cie, ni les setters.

L'attribut readonly répond à tes deux premières questions.

schema.yml

Code : Tout sélectionner

vue: _attributes: { readOnly: yes } ...
Quant à la 3e, Propel permet de mettre du SQL quelque part qui sera toujours exécuté mais pas ecrasé lors des régénérations. Tu peux ainsi créer un fichier "data/sql/view.sql" dans lequel tu vas mettre les instructions SQL pour initialiser ta vue, et dans ton fichier "data/sql/sqldb.map" (qui recense les fichiers SQL à exécuter lors de l'initialisation) et y ajouter une ligne "view.sql=propel".

data/sql/view.sql

Code : Tout sélectionner

CREATE OR REPLACE VIEW vue (...) AS ...;
data/sql/sqldb.map

Code : Tout sélectionner

# Sqlfile -> Database map lib.model.schema.sql=propel plugins.sfGuardPlugin.lib.model.schema.sql=propel view.sql=propel <---- c'est cette ligne qu'on ajoute

Posté : 21 févr. 2009, 20:38
par Calimero
Merci naho :pouce: Je testerai ça plus tard mais ça a l'air impec tout ça.

Posté : 22 févr. 2009, 16:22
par Invité
Bonjour,

Naholyr puisque ta l'air de bien connaître le sujet j'ai une question supplémentaire.

J'ai une vue nommé client (avec une clef primaire nommé "id") et une table contrat qui possède une clef étrangère "client_id" vers l'"id" de la vue client.
J'ai suivi ta méthode et cela fonctionne parfaitement mais j'ai un problème avec l'insertion des données.

J'essaye d'ajouter des données grâce au fichier fixtures.yml.

Code : Tout sélectionner

Contrat: contrat_actif_1: client_id: 1 remarque: Réseau local
Ensuite j'exécute : symfony propel-data_load
Mais j'obtiens l'erreur suivante : The object "1" form class "Client" is not defined in your data file.
Pourtant ma vue client contient bien un client avec l'identifiant 1.

J'ai expliqué un peu plus mon problème sur le forum de Symfony mais je n'ai obtenu aucune réponse :
http://forum.symfony-project.org/index.php/t/19151/

Merci pour vos avis.

Posté : 22 févr. 2009, 16:52
par naholyr
Là ça touchera à la limite de mes connaissances qui restent théoriques sur les vues, puisque je n'en ai pas encore utilisées :?
Donc pour être honnête : aucune idée :O

À vue de nez je dirais qu'il s'agit d'un problème d'ordre de chargement des données.

Cela dit de manière générale je n'aime pas les fixtures qui ont longtemps été buggées, qui pompent énormément de ressources (impossible de faire un vrai dump/restore) et qui sont trop verbeuses.

Posté : 23 févr. 2009, 10:01
par Invité
OK merci Naholyr.
Les données sont déjà référencées par la vue donc je ne peux pas charger ces données encore plutôt.
Mais je note ta remarque sur les fixtures et je pense que je vais devoir me passer de cette fonctionnalité.
Je vais tout même ouvrir un ticket au support car cela ressemble fort à un bug ou du moins à un cas non prise en charge.

Posté : 02 mars 2009, 15:29
par Calimero
Retour au sujet car visiblement l'option readOnly n'a pas réglé tous mes soucis.

Ca avance quand même, je suis tombé sur ce lien qui suggère d'ajouter le flag skipSql à la table.

Ce qui me donne :

Code : Tout sélectionner

produits: _attributes: readOnly: true skipSql: true id: ...
Et là effectivement :

Code : Tout sélectionner

E:\monsite>symfony propel-build-sql ... [propel-sql] + (skipping) produits [propel-sql] + const_brands [builder: MysqlDDLBuilder]
Il a effectivement sauté la construction de ma table produits, ce qui est parfait. J'ai maintenant une table (ou vue) qui est bel et bien gérée, mais ne sera pas altérée par le framework au cours de mon développement !

Je suppose (à vérifier) que l'option readOnly s'applique elle au niveau des données (par exemple lors d'un delete, insert ou update en sql). skipSql permettant donc de sauter la construction de la structure de la table.

Résolu !