Vérification de l'existence d'une donnee dans la Table

Lenouveauapprenti Messages postés 300 Date d'inscription samedi 22 décembre 2018 Statut Membre Dernière intervention 7 avril 2024 - Modifié le 4 avril 2024 à 11:48
mamiemando Messages postés 33120 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 21 mai 2024 - 8 avril 2024 à 13:56

Bonjour,

Environnement de codification : Python 3.12

Espace de codification : Visual Studio

Je cherche à vérifier l'existence d'une donnée avant de la validation l'enregistrement.

Je vous reconnaissant de corriger mon code qui suit:

    # Vérification de l'existence d'une variable
    def Verification(self):
        con = pymysql.connect(
            host="localhost",
            user="root",
            password="",
            database="bdagenda"
        )

        cur = con.cursor()
        cur.execute("select * from Contacts")
        NOrd = self.NOrdre_var.get()
        if len("Contacts") == NOrd:
            messagebox(
                "Attention ! Le n° d'ordre  "
                + NOrd + " existe déjà"
            )
            return
        else:
            pass
        con.commit()
        con.close()


Windows / Chrome 123.0.0.0

A voir également:

6 réponses

jee pee Messages postés 39763 Date d'inscription mercredi 2 mai 2007 Statut Modérateur Dernière intervention 22 mai 2024 9 196
Modifié le 2 avril 2024 à 18:00

Bonjour,

Si tu cherches à vérifier si un n° existe déjà, il suffirait de faire une requête comme

select numord from contacts where numord=numérorecherché

et si c'est pour attribuer un nouveau n° on peut rechercher le dernier attribué par

select max(numord) from contacts

Mais avec une bdd, on peut s'éviter ces soucis en créant un ID autoincrément qui sera généré par le SGBD lors de l'insert d'un nouvel enregistrement.


1
mamiemando Messages postés 33120 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 21 mai 2024 7 753
4 avril 2024 à 11:55

Bonjour,

En complément de la réponse de jeepee, qui me paraît répondre à ton problème, j'aimerais signaler un point qui me paraît incorrect dans ton code.

  • D'une part, Lorsque tu ouvres une connexion, mais d'une part tu ne contrôles pas si la connexion est valide
  • D'autre part tu ne la fermes pas systématiquement. Pour éviter ce genre d'erreur de programmation, je te recommande d'utiliser un context manager (voir mot clé with, comme expliqué ici).
  • Enfin, il n'est pas efficace de se connecter/déconnecter à chaque requête, il vaut mieux se connecter, faire toutes requêtes qu'on a à faire, puis se déconnecter.

Bonne chance

1
Lenouveauapprenti Messages postés 300 Date d'inscription samedi 22 décembre 2018 Statut Membre Dernière intervention 7 avril 2024 2
Modifié le 6 avril 2024 à 14:26

Bonjour,

Tout d'abord, un grand merci à jee pee et mamiemando pour leur réactivité.

Cependant, le problème persiste. J'ai repris le code en suivant vos réponses, mais la solution résout le problème à moitié. En cas de doublon, le message d'alerte est renvoyé, or lorsqu'il s'agissait d'un nouveau numéro, le message d'alerte est renvoyé et une fois je clique sur OK du message, la commande Ajouter s'exécute.

Le code est comme suit. Merci d'avance pour toute aide.

#Creation de la Classe
class Agenda:
    def __init__(self, root):
        self.root = root
        self.root.geometry('1330x616+1+1')
        self.root.title("MezApp'S Agenda")
        self.root.resizable(False, False)
        self.root.configure(bg='#1F0556')
        titre = Label(self.root, text='Repertoire des contacts',
                      bg='#05562E', fg='white', font=('Tajawal', 14, 'bold'))

    def Verification(self):
        con = pymysql.connect(
            host='localhost',
            user='root',
            password='',
            database='bdagenda')
        cur = con.cursor()
        NOrd = self.NOrdre_var.get()
        cur.execute("select N_Ordre from Contacts where N_Ordre=%s", 
        NOrd)
        if NOrd:
            messagebox.showerror('Attention !', message="Risque de 
            doublon. Le N° :"+" "+self.NOrdre_var.get()+" "+"existe 
            deja")
        return
                          
        con.commit()
        con.close()

:

0
yg_be Messages postés 22804 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 22 mai 2024 1 469
6 avril 2024 à 14:32

bonjour,

je remplacerais les lignes de 20 à 22 par:

        cur.execute("select count(*) as c from Contacts where N_Ordre=%s", 
        NOrd)
        ncount=cur.fetchone()[0]
        if ncount > 0 :
0
mamiemando Messages postés 33120 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 21 mai 2024 7 753
Modifié le 6 avril 2024 à 14:37

Bonjour,

En terme d'identifiant pur, le code est bizarrement écrit. En MySQL, je ne pense pas qu'il soit possible d'écraser un enregistrement si son ID est déjà utilisé (en admettant que cette colonne soit bien déclarée UNIQUE, ou mieux, PRIMARY KEY). Si c'est bien le cas, faire une vérification n'a pas vraiment d'intérêt. Il suffit d'insérer en étant optimiste sur le fait que l'ID est disponible et au besoin, rattraper l'exception si l'ID est déjà consommé.

Mais surtout, en MySQL, on peut faire beaucoup mieux : tu devrais utiliser une table dont la colonne ID devrait être AUTO_INCREMENT (ce que permet mysql). Ainsi, dans ton code, tu n'aurais jamais à te préoccuper de l'ID (en particulier à l'insertion d'un enregistrement).

Si cette solution ne te convient pas, peut-être que cette discussion peut te donner des idées de requêtes plus adaptées à tes besoin. Toutefois je me permets d'insister : ces contraintes devraient être traitées par le SGBD (donc le serveur mysql) et pas au niveau des requêtes faites par le client mysql (ici ton code python). Ainsi tu garantis la cohérence de ta base, indépendamment des clients qui interagissent avec.

Bonne chance

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Lenouveauapprenti Messages postés 300 Date d'inscription samedi 22 décembre 2018 Statut Membre Dernière intervention 7 avril 2024 2
7 avril 2024 à 00:09

Bonjour;

Je comprends votre souci, l'Id est auto-incrémenté, ce que je cherche a assimiler est comment je pourrai vérifier l'existence d'un autre élément tel le nom ou le numéro de téléphone. 

en tout cas je vous suis a vous et aux autres de vos réactivités

0
mamiemando Messages postés 33120 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 21 mai 2024 7 753
Modifié le 8 avril 2024 à 14:13

Bonjour

En réponse à #6 :

  • Si tu veux vérifier l'existence d'un élément pour éviter d'insérer un doublon, comme je te l'ai dit, le mieux est d'utiliser UNIQUE (si l'attribut n'est pas la clé, par exemple le numéro de téléphone) ou PRIMARY KEY (si l'attribut est l'index). Dans ce cas, on n'a pas besoin de vérifier : on fait l'insertion, et si elle échoue, c'est qu'il y avait déjà un exemplaire en base.
  • Si tu veux vérifier l'existence d'un élément à d'autre fins, il faut effectivement interroger ta base et compter le nombre d'élément qui coïncident avec ta requête.

Voyons cette seconde approche plus en détail. Supposons que la requête soit :

SELECT COUNT(*)
FROM Contacts
WHERE nom = "Dupont";

On commence par vérifier que le résultat est celui attendu dans un client SQL (par exemple phpmyadmin, ou directement mysql). Ensuite, on l'injecte dans du code python par exemple en s'inspirant de cet exemple.

import pymysql.cursors

# Connect to the database
connection = pymysql.connect(
    host='localhost',
    user='my_sql_user',
    password='my_sql_password',
    database='bdagenda;
    cursorclass=pymysql.cursors.DictCursor
)

with connection:
    with connection.cursor() as cursor:
        # Read a single record
        name = 'Dupont'
        sql = "SELECT COUNT(*) FROM `Contacts` WHERE `nom`=%s"
        cursor.execute(sql, (nom,))
        result = cursor.fetchone()
        print(result)
        if result > 0:
            print("%s is already in Contacts" % nom)

Ensuite il suffit simplement de récupérer le résultat du COUNT dans le code python pour adapter ce que tu dois faire.

Je profite de ce message pour attirer ton attention sur la manière dont tu administres ta base de données.

  • Actuellement, tu te connectes en root (ce qui est mal, car root ne doit être utilisé que pour administrer le serveur MySQL) alors que tu devrais avoir un utilisateur dédié pour ton application (disons agenda), dont les droits ne lui permettent que d'interagir avec la base agenda.
  • De plus, ton compte root n'a pas de mot de passe, ce qui signifie que ta base est accessible à n'importe qui (c'est donc catastrophique en terme de sécurité).

Je t'invite donc à créer proprement un utilisateur mysql et à assigner la base et les tables adéquates à cette utilisateur (voir ce tutoriel).

Bonne chance

0