Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 9 sur 9
  1. #1
    Invité de passage
    Inscrit en
    août 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : août 2008
    Messages : 16
    Points : 2
    Points
    2

    Par défaut Doctrine : inner join sans relations (alias)

    Bonjour,

    existe-til un moyen d'effectuer une query doctrine avec un innerjoin en utilisant une DB non relationelle?

    Chaque fois que j'utilise ->innerJoin() j'ai une erreur me disant que l'alias n'existe pas.
    le problème c'est que je n'ai pas de relations dans maon schemas.yml (car ce n'ets pas une db relationnelle), j'aimerai donc pouvoir définir le join dans ma query.

    Est-ce possible?

    merci

  2. #2
    Membre éclairé Avatar de sacricri
    Profil pro Jean-Philippe Morvan
    Inscrit en
    juin 2008
    Messages
    324
    Détails du profil
    Informations personnelles :
    Nom : Jean-Philippe Morvan
    Âge : 30

    Informations forums :
    Inscription : juin 2008
    Messages : 324
    Points : 342
    Points
    342

    Par défaut

    Bonjour,

    Tu peux toujours faire du DQL en écrivant ta requête complète (cf doc)

  3. #3
    Invité de passage
    Inscrit en
    août 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : août 2008
    Messages : 16
    Points : 2
    Points
    2

    Par défaut

    Salut,

    oui si je ne trouve pas de solution je passerai par cette méthode.

    le seul truc qui est moins bien avec cette façon de faire c'est que c'est moins secure (pour les sql injection par exemple).
    ici j'utilise ce type de synthaxe pour spécifier des valeures : Si j'écrit la requête complète directement existe-t-il un moyen d'assurer un niveau de protection comme c'est le cas avec le remplacement d'un ? par une variable (comme dans l'exemple ci dessus)?

  4. #4
    Membre éclairé Avatar de sacricri
    Profil pro Jean-Philippe Morvan
    Inscrit en
    juin 2008
    Messages
    324
    Détails du profil
    Informations personnelles :
    Nom : Jean-Philippe Morvan
    Âge : 30

    Informations forums :
    Inscription : juin 2008
    Messages : 324
    Points : 342
    Points
    342

    Par défaut

    Citation Envoyé par Lopimp Voir le message
    Si j'écrit la requête complète directement existe-t-il un moyen d'assurer un niveau de protection comme c'est le cas avec le remplacement d'un ? par une variable (comme dans l'exemple ci dessus)?
    Bonne question, je ne saurai te répondre. Regarde du côté de la librairie Doctrine et du code de where() pour te donner une idée.

    Sinon, je n'arrive pas à comprendre. Tu fais un where() mais un leftJoin() ne fonctionne pas ? Quelle est l'erreur affichée ?
    symfony power user !

  5. #5
    Invité de passage
    Inscrit en
    août 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : août 2008
    Messages : 16
    Points : 2
    Points
    2

    Par défaut

    voici l'erreur que j'ai
    Code :
    1
    2
    500 | Internal Server Error | Doctrine_Table_Exception
    Unknown relation alias
    et voici la query que j'essaye d'exécuter
    Code :
    1
    2
    3
    4
    5
    6
    7
    return Doctrine_Query::create()
                        ->select("s.*,t.*")
                        ->from("Sac s")
                        ->innerJoin('Type t ON t.id_type = s.id_type')
                        ->where("s.name=?",$name)
                        ->groupby("s.name")
                        ->execute();
    le problème ici c'est que j'essaye de faire ma query sans utiliser d'alias vu que je n'en ai pas (ma DB n'est pas relationnelleil n'y a donc pas de connections dans mon fichier shemas.yml)

    j'ai essayé pas mal de synthaxe différentes dans ma query, mais à chaque fois il me dit qu'il ne trouve pas l'alias, comme si il fallait obligatoirement fournir un alias.

  6. #6
    Expert Confirmé Sénior
    Avatar de Michel Rotta
    Homme Profil pro Michel Rotta
    Responsable d'exploitation informatique
    Inscrit en
    septembre 2005
    Messages
    4 912
    Détails du profil
    Informations personnelles :
    Nom : Homme Michel Rotta
    Âge : 51
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable d'exploitation informatique
    Secteur : Distribution

    Informations forums :
    Inscription : septembre 2005
    Messages : 4 912
    Points : 7 285
    Points
    7 285

    Par défaut

    Comment peux-tu utiliser une base de données non relationnel avec Doctrine, toutes les bases qu'ils utilisent sont des SGBDR donc si tu utilises Doctrine, ta base EST relationnel.

    Donc, autre possibilité, tu utilises une base de donnée relationnel déjà existante dans la quel la partie relationnel n'est pas déclarée.

    Dans ce deuxième cas, tu peux parfaitement les définires dans ton schema.yml et les utiliser, tant que tu n'injecte pas le SQL, tu ne modifieras que tes objets model qui n'impactent pas ta base. Tu vas y perdre quelques contraintes au niveau de la base, mais elle seront reprises au niveaux du modèle.

    Si non, je serais bien curieux de connaître quel base de données tu utilises. Pour rajouter un lien, ta requête devient.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
     
    return Doctrine_Query::create()
                        ->select("s.*,t.*")
                        ->from("Sac s, Type t")
                        ->where("s.name=?",$name)
                        ->andWhere(s.id = t.sac_id)
                        ->groupby("s.name")
                        ->execute();
    j'ai mis le sens de la relation (andWhere) au hasard, il faudrait donc affiner.
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

  7. #7
    Invité de passage
    Inscrit en
    août 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : août 2008
    Messages : 16
    Points : 2
    Points
    2

    Par défaut

    Salut mimi68,

    effectivement il s'agit bien d'une base de donnée relationnelle mais ou aucune relation n'é été définie (je récupère un ancien projet que je dois migrer sous symfony).

    Donc finalement si je veux pouvoir utiliser ce type de syntaxe, je dois obligatoirement recréer les relations, il n'y a pas moyen de définir les jointures dans le DQL comme dans une query normale?

    A votre avis, quel est la meilleure façon de procéder pour rajouter ces relations sans perdre de données dans la DB existantes? faire les changements dans le DB puis regénérer le ficher schema.yml ou l'inverse?
    (je préfère que la DB soit en phase avec le schemas, car je pourrait être ammené à exécuter des commandes dans un sens ou dans l'autre dans l'avenir)

    merci pour vos réponses

  8. #8
    Invité
    Invité(e)

    Par défaut

    Normalement, rajouter des relations devrait juste rajouter des contraintes dans ta base de données.

    Je dirais que tu as deux solutions. La première :
    - Un dump complet de la base au cas où, ça sert toujours ^^
    - Un dump des données dans des fixtures
    - Ajout des relations dans ton schema.
    - Reconstruction de ton model & base de données
    - Insertion des fixtures que tu as dumpées.

    Ou sinon la 2ème :
    - Un dump complet de la base au cas où, ça sert toujours ^^
    - T'assurer que ton model est bien buildé dans sa version actuelle
    - Modifier le schema.yml en ajoutant tes relations
    - lancer la tache doctrine:generate-migration-diff : elle génère des classes de migrations doctrine selon les différences entre ton model actuellement buildé et ton schema.yml. Voilà pourquoi il faut bien que ton model ne soit pas rebuildé après avoir modifié ton schema.yml car sinon il verra pas de différence.
    - Une fois les classes de migration correctement générées (tu peux vérifier dans lib/migration/doctrine ce qu'elles contiennent) tu peux rebuilder ton model.
    - Et pour finir, tu lances la migration (doctrine:migrate je crois ?)

  9. #9
    Expert Confirmé Sénior
    Avatar de Michel Rotta
    Homme Profil pro Michel Rotta
    Responsable d'exploitation informatique
    Inscrit en
    septembre 2005
    Messages
    4 912
    Détails du profil
    Informations personnelles :
    Nom : Homme Michel Rotta
    Âge : 51
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable d'exploitation informatique
    Secteur : Distribution

    Informations forums :
    Inscription : septembre 2005
    Messages : 4 912
    Points : 7 285
    Points
    7 285

    Par défaut

    Tu as une troisième solution.

    Et qui est, à mon avis la seul solution viable.

    Tu récupères le schéma actuel de ta base. Puis, tu n'y touche plus du tout.
    Tu modifie le schéma en rajoutant les liens et éventuelles contrôles que tu souhaites avoir.
    Tu crée 3 nouvelles bases sur un serveur différents, tu crées : une base pour le dev, une pour le test et une pour les validations fonctionnel de la nouvelle application.
    Tu peux récupérer (voir explication de Tirkyth) une partie des données dans des fixtures.
    Ton schéma va évoluer dans le développement (pas sur mais probable), donc tu travails cool, sans toucher à l'application, tu tests, tu fais valider.
    Une fois le projet terminé, tu passes à la fin de la deuxièmes explication de Tirkyth pour générer les procédures sql qui vont migrer la base de donnée.
    L'idéal serait de tester la migration sur une copie de la base de données et de relancer les test sur cette copie et de la remettre en validation.
    Puis, on peut penser à le faire sur la base de prod (après, bien sur, une bonne sauvegarde).

    Ca, c'est si tes fonctionnalités ne doivent pas être intégrée petit à petit à l'application de prod. Si c'était le cas, on en reparle.
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •