IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PostgreSQL Discussion :

[PostGre 8.3] HERITAGE et pb insertion table d'association


Sujet :

PostgreSQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 68
    Par défaut [PostGre 8.3] HERITAGE et pb insertion table d'association
    Bonjour,

    j'ai dans mon modèle physique de données, quatres tables (A1,A2,A3,A4) qui héritent d'une table (A)

    cette "table-mère" reçoit les identifiant autoincrémentés et d'autres données des "tables filles".

    ces clés primaires, autoincrémentés, des "tables-filles" viennent alimenter la clé primaire de la "table-mère".

    cette "table-mère" est en relation avec une autre table (table "B") par le biais d'une table issue d'association (table "A_B").

    j'ai un problème lors de l'insertion des données dans cette table issue d'association.

    il me dit que la clé étrangère dans "A_B" fait référence à des données inexistantes dans "A". or mes données sont bien présentes dans "A".

    j'ai essayé de supprimer les "tables filles" de "A". et là l'insertion dans la table "A_B" ne me renvoi pas d'erreur.

    est-ce un problème connu des relations d'héritage ?

    plus étonnant, c'est que dans mon modèle, j'ai d'autres relations d'héritage et des liens avec des tables issues d'associations (la même architecture avec moins de "tables filles") et ça fonctionne sans problème.

    ???

  2. #2
    Modérateur
    Avatar de Chtulus
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2008
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Santé

    Informations forums :
    Inscription : Avril 2008
    Messages : 3 094
    Par défaut
    Bonjour,

    Tu aurais un jeu d'essais s'il te plait.

    Sous quel SGBD travail tu ?

    « Je ne cherche pas à connaître les réponses, je cherche à comprendre les questions. »
    - Confucius -

    Les meilleurs cours, tutoriels et Docs sur les SGBD et le SQL
    Tous les cours Office
    Solutions d'Entreprise



  3. #3
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 68
    Par défaut
    Bonjour,

    et merci de vous intéresser à ce problème.

    je travailles dans postgres 8.3 sous windows.

    voilà un exemple, et les requêtes de création de tables :

    TABLE PARCELLE
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    CREATE TABLE parcelle
    (
      id_parcelle serial NOT NULL,
      insee character varying(5) NOT NULL,
      section character varying(5) NOT NULL,
      parcelle character varying(4) NOT NULL,
      CONSTRAINT cle_par PRIMARY KEY (id_parcelle),
      CONSTRAINT fkey_section FOREIGN KEY (insee, section)
          REFERENCES section (insee, section) MATCH SIMPLE
          ON UPDATE NO ACTION ON DELETE NO ACTION
    )
    WITH (OIDS=FALSE);
    ALTER TABLE parcelle OWNER TO postgres;
     
    -- Index: fkidx_sect
     
    -- DROP INDEX fkidx_sect;
     
    CREATE INDEX fkidx_sect
      ON parcelle
      USING btree
      (insee, section);
    j'ai volontairement enlevé la géométrie de la table parcelle car, ça ne sert à rien pour les tests.

    TABLE OPEFON
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    CREATE TABLE opefon
    (
      id_opef serial NOT NULL,
      date date NOT NULL,
      proprio character varying(30) NOT NULL,
      CONSTRAINT cle_opef PRIMARY KEY (id_opef)
    )
    WITH (OIDS=FALSE);
    ALTER TABLE opefon OWNER TO postgres;
    TABLE AXI
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE axi
    (
    -- Hérité(e):   id_opef integer NOT NULL DEFAULT nextval('opefon_id_opef_seq'::regclass),
    -- Hérité(e):   date date NOT NULL,
    -- Hérité(e):   proprio character varying(30) NOT NULL,
      disponibilite boolean NOT NULL DEFAULT true,
      anex character varying(50) NOT NULL,
      CONSTRAINT cle_axi PRIMARY KEY (id_opef)
    )
    INHERITS (opefon)
    WITH (OIDS=FALSE);
    ALTER TABLE axi OWNER TO postgres;
    TABLE CD
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE cd
    (
    -- Hérité(e):   id_opef integer NOT NULL DEFAULT nextval('opefon_id_opef_seq'::regclass),
    -- Hérité(e):   date date NOT NULL,
    -- Hérité(e):   proprio character varying(30) NOT NULL,
      CONSTRAINT cle_cd PRIMARY KEY (id_opef)
    )
    INHERITS (opefon)
    WITH (OIDS=FALSE);
    ALTER TABLE cd OWNER TO postgres;
    TABLE PAROF
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    CREATE TABLE parof
    (
      id_parcelle serial NOT NULL,
      id_opef serial NOT NULL,
      CONSTRAINT cleparof PRIMARY KEY (id_parcelle, id_opef),
      CONSTRAINT fk_opef FOREIGN KEY (id_opef)
          REFERENCES opefon (id_opef) MATCH SIMPLE
          ON UPDATE NO ACTION ON DELETE NO ACTION,
      CONSTRAINT fk_par FOREIGN KEY (id_parcelle)
          REFERENCES parcelle (id_parcelle) MATCH SIMPLE
          ON UPDATE NO ACTION ON DELETE NO ACTION
    )
    WITH (OIDS=FALSE);
    ALTER TABLE parof OWNER TO postgres;
    et voici ce que ça donne sous PGAdmin III:



    de haut en bas : axi, cd, opefon (cachée par parof), parcelle et à droite parof (la table issue de l'association de parcelle et opefo) avec le message d'erreur lorsque j'essaye d'insérer à la main.

    j'espère que ça suffira, s'il vous faut autre chose, je suis à votre disposition.

    cordialement.
    Images attachées Images attachées  

  4. #4
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Je trouve étrange cette partie là :
    Citation Envoyé par nponzo Voir le message
    ces clés primaires, autoincrémentés, des "tables-filles" viennent alimenter la clé primaire de la "table-mère".
    Si je comprends bien, tu crées une ligne dans la table fille avant la ligne correspondante dans la table mère et la clé primaire de la table fille est auto-incrémentée ?
    Ne peut-il arriver un cas où le même identifiant existe dans deux tables filles ?
    N'y aurait-il pas alors conflit dans la table mère ?

    Perso je ferais plutôt le contraire :
    - Création de la ligne dans la table mère
    - Récupération de l'id créé et insertion dans la table fille.

    Dans un héritage, on a par exemple les associations :
    Employe -1,1----Etre---- Personne
    Contact -1,1----Etre---- Personne
    Personne est ici l'entité mère et Employe et Contact sont les entités filles.

    Si je passe du MCD au MPD, ça donne :
    T_Personnes_Per(Per_Id, Per_Nom, Per_Prenom, ...)
    T_Employes_Emp(Emp_IdPersonne, Emp_Salaire, ...)
    T_Contacts_Ct(Ct_IdPersonne, Ct_IdOrganisme, ...)

    C'est donc bien la table mère qui doit donner sa clé primaire aux tables filles et non l'inverse.

    J'ajoute que, évidemment, les tables associatives contenant une clé étrangère faisant référence à la clé primaire de la table mère ou d'une table fille sont alimentées après l'insertion de la ligne dans les tables de l'héritage. Dans l'exemple ci-dessus, ce serait le cas si on externalise les adresses des personnes :
    Personne -0,n----Habiter----0,n- Adresse
    T_Adresses-Adr(Adr_Id, Adr_Rue, Adr_Ville, Adr_CP, ...)
    T_Personnes_Per((Per_Id, Per_IdAdresse, Per_Nom, Per_Prenom, ...)

    EDIT : Tu as posté le détail pendant que j'écrivais mon message.
    Je ne savais pas que Postgres implantait directement le concept d'héritage. Intéressant !
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  5. #5
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 68
    Par défaut
    bonjour,


    Cinephil

    je me serais trompé de sens ? bin mince alors, je vais essayer comme vous dites.

    Pour répondre aux questions posées, j'alimente d'abord les tables filles et postgres remplis les tables mères comme vous avez dit

    c'est lui qui gère les clés primaires. je n'ai donc pas remplis les champs "id" des tables axi et cd (voir image post précédent) et il à mis automatiquement 5 et 6 dans cd. il à autoincrémenté à la suite, tout seul. mais je ne sais pas s'il peut se tromper à la longue ou autre (mais je ne vois pas de raison).

    _______________________________________________________________

    pour l'autre exemple d'héritage dans ma base entre "personne" et "exploitation", j'ai bien remplis les tables filles avant (car personne_physique à un champs en plus [date de naissance], que personne_morale, dont n'hérite pas "personne" mais je n'ai pas mis d'identifiant auto incrémenté. j'ai utilisé des entiers et j'ai chargé les données à partir d'une table d'export qui contenait un identifiant autoincrémenté.

    plus étonnant, c'est que dans mon modèle, j'ai d'autres relations d'héritage et des liens avec des tables issues d'associations (la même architecture avec moins de "tables filles") et ça fonctionne sans problème.
    même architecture mais pas même types !!!! bourricot de moi

    je suis donc sure de ne pas m'être trompé lors de l'insertion dans les tables filles car les identifiant de personne_morale et personne_physique se suivent.

    en tout cas merci à tous pour vos réponses, j'essaye de voir ce que je peux faire avec ça et j'espère cliquer sur "résolu" le plus vite.

    à bientôt,

    cordialement

    nicolas.

  6. #6
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Je n'ai jamais utilisé Postgres donc je ne me prononcerai pas là dessus mais il faut s'assurer dans la doc que Postgres gère correctement la clé primaire de la table mère si on alimente une table fille.

    INHERITS signifie bien normalement que c'est la fille qui hérite de la mère (de son identifiant et de ses autres attributs) et pas le contraire.

    Il semble que oui puisqu'en fait la table fille ne contient pas d'identifiant en propre mais a pour clé primaire-étrangère la clé primaire de la table mère.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CONSTRAINT cle_axi PRIMARY KEY (id_opef)
    Si ça fonctionne correctement, c'est bien pratique : je crée une fille et la mère est alimentée automatiquement !
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  7. #7
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 68
    Par défaut
    Bonjour,

    en effet, je créé une table fille et les données entrée se trouvent dans la table mère.

    je continu à faire quelques tests, mais je voulais vous dire qu'il y a une erreur dans mon code, ma table issue d'association (parof) contient deux champs autoincrémentés. ça devrait être des entiers qui récupèrent la valeur autoincrémenté des autres tables.

    mais je ne suis pas sure que ça ne vienne que de là.

    en tout cas merci, car au moins ça avance.

    à bientôt,

    cordialement,

    nicolas.

  8. #8
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par nponzo Voir le message
    ma table issue d'association (parof) contient deux champs autoincrémentés.
    Effectivement, une table associative n'a en principe pas de colonne auto-incrémentée, en tout cas pas en tant que clé primaire.
    Elle doit avoir pour clé primaire les clés étrangères faisant référence aux clés primaires des tables qui entrent en jeu dans l'association.

    Il faut changer le type des colonnes id_parcelle et id_opef dans la table parof
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  9. #9
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 68
    Par défaut
    rebonjour.

    cinephil : oui, j'ai changé, mais le pb ne viens pas de là

    l'héritage sous postgres fonctionne correctement quand on insère des données dans les tables filles, qui remplissent automatiquement la table mère.

    on peut même mettre des types "serial" dans les filles et dans les mères ils ne se mélange pas les pinceaux, il remplis correctement les champs.

    mais si on travail dans ce sens là (les filles avant la mère) la table issue d'association ne veut rien savoir. et ne peut pas récupérer les données de la table mère, que ce soit des entier ou non. on dirait que les champs sont fictifs dans la mère quand on fait ça.

    si on rempli la mère d'abord, la table d'association accepte les données mais ne remplit pas automatiquement les données dans les tables filles.

    un déclencheur pourrait peut-être régler le problème car mes tables filles ont des codes uniques.

    je pourrais peut-être lui dire : "si dans telle colonne, code like 'XX%' remplis telle table fille avec telles données, si code like 'YY%' alors remplis telle autre fille.

    que pensez vous d'une telle solution pour ne pas avoir à remplir les filles après avoir remplis les mères ??

  10. #10
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Si tu te décides à abandonner l'héritage de Postgres, reprend la structure proposée par mon message #4.

    Ensuite, ton interface en PHP devra, lors de la saisie d'un nouvel enregistrement :
    1) Créer la ligne dans la table mère
    2) Récupérer l'id inséré (il doit y avoir une fonction pour ça adaptée à Postgres)
    3) Créer la ligne dans la table fille
    4) Créer la ligne dans la table associative

    Tout se passe sur le serveur et l'utilisateur n'y voit que du feu, il croit avoir inséré une seule ligne de données. C'est à ça que ça sert les interfaces homme-machine
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

Discussions similaires

  1. Réponses: 2
    Dernier message: 23/02/2006, 12h23
  2. [MySQL] Problème d'insertion de données dans table d'associations
    Par Yukhaa dans le forum PHP & Base de données
    Réponses: 13
    Dernier message: 07/02/2006, 17h10
  3. Probleme heritage : References sur la table parente
    Par Belgar dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 03/05/2005, 22h11
  4. HELP creation et insertion table....??
    Par aqwel18 dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 09/12/2004, 15h50
  5. [Postgres] Pb d'heritage...
    Par anonia dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 23/08/2003, 22h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo