Partage
  • Partager sur Facebook
  • Partager sur Twitter

DJANGO Suppression objet

Problème de ForeignKey inexistante

Sujet résolu
    3 janvier 2022 à 14:38:47

    Bonjour,

    Apprenant depuis peu Django, je suis face à un problème de liaison de Table. 

    En effet, j'ai modifié / re modifié mes différents modèles. Concrètement, mon problème est qu'un de mes objets a une ForeignKey inexistante, ce qui m'empêche de supprimer / migrate les différents objets.

    Code :

    class jeu(models.Model):
        
        compteTwitter1 = models.ForeignKey(compteTwitter, null=True, on_delete=models.CASCADE, related_name="cT1", db_constraint=False)
    
        compteTwitter2 = models.ForeignKey(compteTwitter, null=True, on_delete=models.CASCADE, related_name="cT2", db_constraint=False)
    
        win = models.ForeignKey(compteTwitter, null=True, on_delete=models.CASCADE, related_name="cT3", db_constraint=False)
    
        tweet = models.ForeignKey(tweet, on_delete=models.CASCADE, db_constraint=False)
    
    
    class compteTwitter(models.Model):
        
        id_compteTwitter = models.IntegerField(null=True)
        name = models.CharField(max_length=100)
    
    class tweet(models.Model):
        
        id_tweet = models.IntegerField(null=True)
        compteTwitter = models.ForeignKey(compteTwitter, null=True, on_delete=models.CASCADE)
        
    
    


    Message d'erreur lorsque je veux utiliser la commande : migrate

    "The row in table 'game_jeu' with primary key '1' has an invalid foreign key: game_jeu.win_id contains a value '1' that does not have a corresponding value in game_comptetwitter.id."

    Message d'erreur lorsque je veux supprimer des objets

    "FOREIGN KEY constraint failed"

    J'ai essayé d'ajouter le paramètre "db_constraint=False" mais cela ne change rien. 

    Sauf erreur de ma part, le problème est qu'un objet "Jeu" a été créé, avec un/des champs faisant référence à un objet compteTwitter via un ID (=ForeignKey) inexistant. Le problème est que je n'arrive plus à modifier quoi que ce soit : je ne peux pas supprimer d'objets, ni utiliser la commande migrate. Autant dire que je suis bloqué :)

    Merci d'avance pour votre aide !

    -
    Edité par EmileHOUPLAIN1 3 janvier 2022 à 14:40:14

    • Partager sur Facebook
    • Partager sur Twitter
      3 janvier 2022 à 15:10:26

      le truc serait de créer une entrée dans la table compteTwitter de façon à ce qu'il y ai un élément qui possède le champ id à 1 (champ id et non pas champ id_compteTwitter) puisque c'est ce qu'il manque
      • Partager sur Facebook
      • Partager sur Twitter
        3 janvier 2022 à 15:24:14

        Bonjour Umfred, encore toi ! :)

        Donc la solution serait de créer les objets "manquants" pour que les références via ForeignKey soient ok. Je comprends bien l'idée, cependant, je ne sais pas bien comment marche Django, si je créé premier objet (il lui sera assigné automatiquement la PrimaryKey 1) et que je le supprime dans la foulée, puis que j'en recréé un, il lui sera assigné automatiquement la PrimaryKey "1" ou "2" ? 

        De plus, je pensais que la PrimaryKey (= l'ID de l'objet) était assigné automatiquement ? Il est possible de "forcer" la valeur d'une PrimaryKey ? 

        Merci !

        • Partager sur Facebook
        • Partager sur Twitter
          3 janvier 2022 à 16:12:21

          en théorie oui, il est possible de le faire (la primary key étant en général (/souvent) un autoincrément, le 1er vaut 1 et les suivants valent 2,3,... sans jamais revenir en arrière (pour ne pas faire planter la base). Mais tu peux peut-être éditer ta base de données "manuellement" via phpMyAdmin ou outils similaires et ajouter manuellement un "comptetwitter" d'id 1

          Si tu n'as pas trop de données, tu peux te permettre de supprimer la base existante pour la recréer avec tes nouvelles contraintes, et remettre les données ensuite.(sinon il faudrait faire un export des données, supprimer les tables et réinsérer les données)

          • Partager sur Facebook
          • Partager sur Twitter
            3 janvier 2022 à 16:45:11

            Merci Umfred pour ces précisions. 

            La deuxième solution (supprimer les données, c'est à dire les objets créés) est celle que j'ai essayé initialement, mais impossible de supprimer les objects via jeu.objects.all().delete() par exemple, message d'erreur : "FOREIGN KEY constraint failed"..

            • Partager sur Facebook
            • Partager sur Twitter
              3 janvier 2022 à 18:14:34

              Bonjour,

              Meilleurs vœux !

              --------------------------

              Tout d'abord et c'est important, ne pas générer soit même ses ID, Django le fait automatiquement, et il y a risque de conflit et d'incompréhension conceptuellement parlant.

              Ensuite, je trouve bizarre que l'IDE ne dise rien concernant ces lignes,

              class jeu(models.Model):
                   
                  compteTwitter1 = models.ForeignKey(compteTwitter, null=True, on_delete=models.CASCADE, related_name="cT1", db_constraint=False)
                  compteTwitter2 = models.ForeignKey(compteTwitter, null=True, on_delete=models.CASCADE, related_name="cT2", db_constraint=False)


              car compteTwitter n'est définie que par la suite à ces lignes.

              Il serait préférable, et c'est peut-être le problème carrément de remplacer les variables par une chaîne de caractères,

              class jeu(models.Model):
                   
                  compteTwitter1 = models.ForeignKey("compteTwitter", null=True, on_delete=models.CASCADE, related_name="cT1", db_constraint=False)
                  compteTwitter2 = models.ForeignKey("compteTwitter", null=True, on_delete=models.CASCADE, related_name="cT2", db_constraint=False)

              le paramètre db_constraint me semble inutile, models.CASCADE est un paramètre qui retire la contrainte ForeignKey lors de la suppression des lignes d'une table.

              • Partager sur Facebook
              • Partager sur Twitter

              Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
              La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

                4 janvier 2022 à 11:46:13

                Bonjour Fred1599, 

                Tout d'abord, merci pour ta réponse et bonne année 2022 :)

                1) Je comprends le principe de ne pas générer les IDs (=primary key) moi même pour éviter tout risque d'erreurs etc. 

                2) L'IDE ne me remonte pas d'erreurs car dans mon code en local le modèle compteTwitter est défini avant le modèle jeu. Mais je pensais que l'ordre de déclaration des différents modèles n'avait pas d'importance ? 

                3)J'ai essayé d'utiliser le paramètre "db_constraint" afin de passer outre de potentielles règles afin de supprimer les données/modèles, mais cela n'a pas fonctionner

                4)Le paramètre models.CASCADE était destiné à dire "Si un des deux comptes twitter lié au jeu est supprimé de la base de donnée, alors supprimer les jeux associés à ce compte twitter supprimé", est ce bien cela que tu entends par "retire la contrainte ForeignKey lors de la suppression des lignes d'une table."


                Merci

                • Partager sur Facebook
                • Partager sur Twitter
                  4 janvier 2022 à 11:53:36

                  est ce bien cela que tu entends par "retire la contrainte ForeignKey lors de la suppression des lignes d'une table."

                  Oui c'est ça en effet !

                  Aussi avant de faire la commande migrate, il te faut créer le fichier de migration avec la commande makemigrations

                  • Partager sur Facebook
                  • Partager sur Twitter

                  Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
                  La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

                    5 janvier 2022 à 10:35:32

                    ui, justement la commande makemigrations marche sans erreur, mais la commande migrate lève une erreur... 

                    J'ai installé DB Browser pour visualiser mes tables / données et voir ce qui pourrait clocher, je fais ca dès que j'ai un peu de temps

                    Merci

                    MAJ (05/01/2022 à 15H26) : 

                    Bonjour, j'ai supprimé toutes mes tables, et donc mes données via l'outil DB Browser, mais lorsque je veux utiliser la commande migrate (après avoir utiliser la commande makemigrations) cela me soulève l'erreur suivante : 

                    Cela fait référence à un ancien champ "comptes" du modèle "jeu" qui a été supprimé depuis. 

                    Comment revenir à zéro ?

                    MAJ (05/01/2022 à 16H26) : 

                    J'ai réussi à régler le problème en générant une nouvelle BDD via DB Browser à partir de rien, pour remplacer l'existante, puis j'ai refais tourner les commandes "makemigrations" et "migrate". Pas d'erreurs. 

                    Merci,

                    Emile

                    -
                    Edité par EmileHOUPLAIN1 5 janvier 2022 à 16:27:49

                    • Partager sur Facebook
                    • Partager sur Twitter

                    DJANGO Suppression objet

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown