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

Python Discussion :

Sqlite3 : activer foreign_keys


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Avatar de antoinev2
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    177
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 177
    Par défaut Sqlite3 : activer foreign_keys
    Bonjour, j'ai un problème quand je manipule une BDD SQLite3 via Python, concernant les commandes PRAGMA, à savoir foreign_keys.

    Les tables concernées sont la table adresse, "T_d_Adresse", et la table personne, "T_d_Personne".
    Dans la structure de la BD, je rattache chaque "personne" à une "adresse" (et je peux rattacher plusieurs personnes à la même adresse).
    On retrouve donc le champ "id_adresse" :
    • dans la table T_d_Adresse, où il est la clé primaire
    • dans la table T_d_Personne, où il est une clé étrangère


    J'arrive à activer foreign_keys quand je manipule ma BDD par la console de windows.
    Voici un exemple dans lequel ma tentative de suppression échoue, grâce à l'intégrité référentielle :



    Et voici ce qui se passe quand j'essaie de faire la même chose mais à partir du shelle de l'IDLE : je n'arrive pas à activer foreign_keys (impression écran ci-dessous en deux parties) :


  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 690
    Par défaut
    Par défaut, les foreign keys ne sont pas activées, d'ailleurs dans l'exemple sqlite vous le mettez en route via PRAGMA foreign_keys=ON.
    Avec Python, c'est pareil: il faudra exécuter le SQL 'PRAGMA foreign_keys=ON;' via cursor.execute.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre confirmé
    Avatar de antoinev2
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    177
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 177
    Par défaut
    Merci pour ta réponse, et justement c'est ce que j'essaie de faire...
    à tout hasard je viens de retenter avec le point-virgule de fin, au cas où, mais ensuite lorsque je tente de supprimer une donnée "adresse" à laquelle est rattachée une donnée "personne", eh bien la suppression fonctionne.

    Je passe à côté de quelque chose, mais quoi...

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 690
    Par défaut
    Postez du code pouvant être facilement exécuté via un cut&paste qui reproduit ce qui vous ennuie.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre confirmé
    Avatar de antoinev2
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    177
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 177
    Par défaut
    Ok, alors voici déjà un lien pour télécharger la base de données : CarnetAdresse.db

    Et voici le code que j'exécute dans le shell de l'IDLE :
    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
    #importer le module et se connecter
    import sqlite3
    cnx = sqlite3.connect('D:/CarnetAdresse.db')
    curs = cnx.cursor()
    #lister les personnes
    for row in curs.execute('SELECT id_personne, prenom, nom, id_adresse FROM T_d_Personne'):
        print row
    #lister les adresses
    for row in curs.execute('SELECT id_adresse, cp, ville FROM T_d_Adresse'):
        print row
    #activer les foreign_keys
    curs.execute("PRAGMA foreign_keys=on")
    #supprimer l'adresse 9, à laquelle la personne Joe Lecowboy est rattachée
    curs.execute('DELETE FROM T_d_Adresse WHERE id_adresse=9')
    #valider la suppression
    cnx.commit()
    #lister les adresses
    for row in curs.execute('SELECT id_adresse, cp, ville FROM T_d_Adresse'):
        print row
    #et se déconnecter
    curs.close()
    cnx.close()

  6. #6
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    L'activation est facile à faire, et il n'est même pas nécessaire d'ouvrir un curseur. Après avoir obtenu une connexion avec connect, on fait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cnx.execute("PRAGMA foreign_keys=on;")
    Et il faut le faire à chaque nouvelle connexion avec la base.

  7. #7
    Membre confirmé
    Avatar de antoinev2
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    177
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 177
    Par défaut
    Oui, je sais, Google m'a amené vers ton site Tyrtamos et j'y ai découvert la possibilité d'exécuter une requête sans passer par un objet Cursor.
    Merci d'ailleurs, ça fait plaisir d'apprendre qqch.

    J'ai testé bien sûr mais je n'arrive pas à faire fonctionner ça...
    Voici ci-dessous un exemple avec les résultats :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    import sqlite3
    cnx = sqlite3.connect('D:/CarnetAdresse.db')
    cnx.execute("PRAGMA foreign_keys=on;")
    <sqlite3.Cursor object at 0x011C5380>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for row in cnx.execute('SELECT id_adresse, cp, ville FROM T_d_Adresse'):
        print row
    (1, u'0', u'NC')
    (2, u'75000', u'Paris')
    (3, u'35000', u'Rennes')
    (4, u'59000', u'Roubaix')
    (5, u'75000', u'Paris')
    (6, u'29000', u'Brest')
    (7, u'64000', u'PAU')
    (8, u'64320', u'ARESSY')
    (9, u'64640', u'HELETTE')

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cnx.execute('DELETE FROM T_d_Adresse WHERE id_adresse=9')
    <sqlite3.Cursor object at 0x011C5200>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    cnx.commit()
    for row in cnx.execute('SELECT id_adresse, cp, ville FROM T_d_Adresse'):
        print row
    (1, u'0', u'NC')
    (2, u'75000', u'Paris')
    (3, u'35000', u'Rennes')
    (4, u'59000', u'Roubaix')
    (5, u'75000', u'Paris')
    (6, u'29000', u'Brest')
    (7, u'64000', u'PAU')
    (8, u'64320', u'ARESSY')

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    curs.close()
    cnx.close()
    Dans cet exemple, la suppression de l'adresse 9 a réussi : alors que l'intégrité référentielle devrait l'interdire...

    Ou alors le problème se situe ailleurs, mais dans ce cas, pourquoi la même manipulation effectuée depuis la console windows donne le résultat qui me semble logique, à savoir que la suppression est interdite?

    J'hésitais depuis tout-à-l'heure mais j'en ai besoin, tant pis pour le mur

  8. #8
    Membre confirmé
    Avatar de antoinev2
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    177
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 177
    Par défaut
    Bonjour, et mauvaise nouvelle : pas d'erreur de mon côté, la requête est exécutée.

    Ca peut être par rapport à la version de Python? C'est la version 2.6.2 sur mon poste.

    Wiztricks j'avais cru comprendre que tu voulais du code à exécuter comme moi dans le shell, d'où mon post qui suivait ta demande.
    D'ailleurs je n'avais pas encore intégré le code qui pose problème à mon appli.

    Pour tester "dans une appli" et non dans le shell, j'ai repris ton code Tyrtamos, et modifié un peu puisque je suis sous windows, et ajouté quelques print et raw_input :
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    # -*- coding: utf-8 -*-
    from __future__ import division
    # Python 2.6
     
    import sqlite3
     
    #############################################################################
    def ouvrebase(basesql, curseur=False):
        # """ouvre la base concours.db3 et renvoie la connexion
           # si curseur est True, renvoie aussi un curseur
        # """
        try:
            cnx = sqlite3.connect(basesql)
            cnx.execute("PRAGMA foreign_keys=on;") # active le foreign key
        except sqlite3.Error, err:
            raise # renvoie l'exception à l'appelant
        if curseur:
            cur = cnx.cursor()
            return cnx, cur
        return cnx
     
    #############################################################################
    def fermebase(cnx, cur=None):
        # """Ferme la base ouverte avec la connexion cnx
           # si le curseur cur est donné, il est fermé aussi
        # """
        if cur != None:
            cur.close()
        cnx.close()
     
    #############################################################################
     
    # basesql = u"CarnetAdresse.db"
    basesql = u"D:/Test/CarnetAdresse.db"
     
     
    cnx, cur = ouvrebase(basesql, True)
     
    try:
        cur.execute("""DELETE 
                       FROM T_d_Adresse 
                       WHERE id_adresse=9 """)
        cnx.commit()
        print u'requête exécutée avec succès.'
    except sqlite3.Error, err:
        cnx.rollback()
        print u"Erreur", err.args[0]    
     
    fermebase(cnx, cur)
    vSuite = raw_input('tapez entree pour fermer')
    et voici le résultat :


    Et je vérifie le contenu de la table, l'adresse 9 a bien été supprimée :



    Sinon j'ai une solution avec les triggers, en fouillant j'ai retrouvé des tests que j'avais faits il y a un moment et qui fonctionnaient avec ça, dans le shell.
    A vérifier.
    Mais bon j'aimerais comprendre d'où vient le problème...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [langage] Pb avec Active perl :s
    Par Cetras dans le forum Langage
    Réponses: 2
    Dernier message: 02/09/2003, 13h28
  2. Fonction qui s'active lorsqu'un Form bouge
    Par Xavier dans le forum C++Builder
    Réponses: 3
    Dernier message: 22/05/2003, 12h54
  3. [VB6][active x] faire du multi-thread avec vb
    Par pecheur dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 20/05/2003, 12h01
  4. Tester connexion Internet active sous Windows
    Par Altau dans le forum Développement
    Réponses: 3
    Dernier message: 12/08/2002, 12h43
  5. [Kylix] Clé d'activation
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 27/03/2002, 23h19

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