Insert SQL

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour, Je voudrais insérer dans un enregistrement de ma bdd un grand nombre de valeurs. Un enregistrement possède 124 champs. Toutes mes données sont dans un tableau, l'idée est donc de parcourir ce tableau pour enregistrer un valeur à chaque champ.

1
2
3
4
5
6
7
def insertDAE(server, data):
    cursor = server.cursor()
    for value in data:
        print(value)
        cursor.execute("INSERT INTO dbo.SQL#DAE_TBL VALUES(%s)", value)
    server.commit()
    server.close()

Je pense que mon problème vient du %s techniquement il en faudrait 124 mais je voudrais trouver une solution pour éviter d'en écrire autant. Pouvez vous me donner des pistes pour m'aider. Merci

+0 -0

Arf oui d'accord j'avais mal compris ta question.

Du coup pourquoi pas préparer ta chaine de caractère avec ta boucle puis ensuite l'envoyer dans ton execute ?

Un truc comme :

1
2
val = ",".join([value for value in data])  # Assemble toutes les valeurs les unes à la la suite des autres
cursor.execute("INSERT INTO dbo.SQL#DAE_TBL VALUES({})".format(val))  # Injecte les valeurs dans la commande

EDIT : C'est ptet crade comme méthode ? J'ai pas l'habitude de bosser avec des bdd…

Édité par Eskimon

ZdS, le best du Zeste ! Tuto Arduino, blog, etc

+0 -0
Staff

un bon moyen, si tu sais combien tu as de ? à mettre c'est simplement

1
2
query = "INSERT INTO dbo.SQL#DAE_TBL VALUES({})".format(",".join("?" * nombre_de_fois))
cursor.execute(query, *tous_tes_parametres_dans_une_liste)

Édité par artragis

+2 -0
Auteur du sujet

Je pense que ta solution fonctionne. Du coup j'ai une autre erreur en rapport avec l'encodage si au passage tu sais comment la résoudre je connais pas bien python mais je devrais trouver. Voici l'erreur UnicodeEncodeError: 'ascii' codec can't encore character u'\xb0'

Une autre question au passage dans mon tableau certaines données peuvent être null, j'avais au début attribué None mais ça me renvoyait une erreur je mets maintenant "null", c'est correct comme méthode?

Édité par NLair

+0 -0
Auteur du sujet

Dans mon tableau qui contient toutes mes valeurs j'ai déjà un u devant chaque valeurs. Et j'ai mis ça en première ligne de mon code # coding: utf8 Apparemment dans mes données que j'ai a enregistré en base c'est le caractère ° qui ne passe pas

Édité par NLair

+0 -0
Auteur du sujet

J'ai plus ou moins réglé mon problème. Je profite de ce sujet pour poser une autre question. Je n'arrive pas à insérer une chaine de caractère avec des espaces dans ma table. Par exemple la chaine "Rue DE MONCEAU" me renvoi une erreur à l'insertion si je met des _ à la place des espaces ça passe. Pourtant dans ma base de donnée je peux bien enregistrer cette donnée sans problème, il s'agit d'un champ nvarchar(65). Pouvez me donner des pistes car pour le moment je ne trouve pas la source de mon erreur.

Merci

+0 -0
Auteur du sujet

Mon problème d'espace n'est pas lié à cette ligne val = ",".join([value for value in data]).encode('utf-8') Mes données sont dans une chaine de caractère séparée par des virgules, la chaine Rue DE MONCEAU n'est donc pas entre guillemet c'est pour ça que les espaces passe pas non?

+0 -0
Auteur du sujet

j'arrive toujours pas régler mon problème, après plusieurs essais je suis arrivé à ça:

1
2
3
4
5
6
7
8
9
def insertDAE(server, data):
    cursor = server.cursor()
    #val = ",".join([value for value in data]).encode('utf-8')
    #cursor.execute("INSERT INTO dbo.SQL#DAE_TBL VALUES({})".format(val))
    val = ', '.join('?' * len(data))
    query_string = 'INSERT INTO dbo.SQL#DAE_TBL VALUES (%s);' % val
    cursor.execute(query_string, val)
    server.commit()
    server.close()

Mais dans tous les cas j'ai le même problème, le type de donnée dans mon tableau. Si je précise pas la première valeur avec des espaces ne passe pas. Si je met en string ça ne passe pas en bdd pour les champs qui sont d'un type différent. Avez vous une idée? je peux par exemple stocker dans mon tableau le type de chaque donnée mais je ne sais pas comment exploiter ça par la suite.

+0 -0
Auteur du sujet

D'accord je veux bien, j'ai essayé plusieurs choses. Et j'arrive à ça:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def insertDAE(server, data):
    cursor = server.cursor()
    #val = ",".join([value for value in data]).encode('utf-8')
    #cursor.execute("INSERT INTO dbo.SQL#DAE_TBL VALUES({})".format(val))
    val = ', '.join('?' * len(data))
    query_string = 'INSERT INTO dbo.SQL#DAE_TBL VALUES (%s);' % val
    for d in data:
        cursor.execute(query_string, d)
    server.commit()
    server.close()

Peux tu me dire ou est le problème au niveau de mes variables? La version en commentaire est elle mieux? Actuellement j'ai cette erreur: TypeError: not all arguments converted during string formatting

+0 -0

Je pense que tu ne comprends pas ce qui se passe. Décryptons ton code précédent :

1
2
3
4
5
6
7
def insertDAE(server, data):
    cursor = server.cursor()
    val = ', '.join('?' * len(data))
    query_string = 'INSERT INTO dbo.SQL#DAE_TBL VALUES (%s);' % val
    cursor.execute(query_string, val)
    server.commit()
    server.close()

À la ligne 3, on crée une chaîne de caractère du type '?, ?, ?, ?' avec autant de points d'interrogation que d'éléments dans data. Testons :

1
2
3
4
>>> data = ['banane', 'fraise', 'kiwi']
>>> val = ', '.join('?' * len(data))
>>> val
'?, ?, ?'

La ligne suivante va ensuite "injecter" cette chaîne dans ta chaîne de requête :

1
2
3
>>> query_string = 'INSERT INTO dbo.SQL#DAE_TBL VALUES (%s);' % val
>>> query_string
'INSERT INTO dbo.SQL#DAE_TBL VALUES (?, ?, ?);'

Enfin, le cursor.execute va remplacer tout les ? par les donnés de data. Il faut donc lui passer dataet non pas val si tu veux un quelconque résultat.

ZdS, le best du Zeste ! Tuto Arduino, blog, etc

+0 -0
Auteur du sujet

D'accord je comprends, merci pour tes explications. J'ai donc passé data en paramètre comme ceci:

1
2
3
4
5
6
7
def insertDAE(server, data):
    cursor = server.cursor()
    val = ', '.join('?' * len(data))
    query_string = 'INSERT INTO dbo.SQL#DAE_TBL VALUES (%s);' % val
    cursor.execute(query_string, data)
    server.commit()
    server.close()

Mais ça me retourne cette erreur: ValueError: 'params' arg can be only a tuple or a dictionary

J'ai donc ajouté cette ligne:

1
    data = ",".join([value for value in data]).encode('utf-8')

Et j'obtiens cette erreur: TypeError: not all arguments converted during string formatting

+0 -0
Staff

Ok, je comprends pourquoi : data est une liste, il faut donc que tu la transforme en "tuple" ou plus précisément en "liste d'arguments". Pour cela, il faut utiliser le "splat operator" aussi connu sous le nom d’astérisque.

Tu aurais donc cursor.execute(query_string, *data).

Pour autant, il faut que tu t'assures que chaque élément est "mettable". une méthode simple est donc de faire précéder le execute d'un map(str, data).

+0 -0
Auteur du sujet

Voici ce que j'ai fais c'est bien ce que tu pensais?

1
2
3
4
5
6
7
8
9
def insertDAE(server, data):
    cursor = server.cursor()
    val = ', '.join('?' * len(data))
    query_string = 'INSERT INTO dbo.SQL#DAE_TBL VALUES (%s);' % val
    data = map(str, data)
    print(data)
    cursor.execute(query_string, *data)
    server.commit()
    server.close()

Par contre * je l'ai peut être mal utilisé, voici l'erreur renvoyé: TypeError: execute takes 1 or 2 arguments (125 given)

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte