Insert SQL

a marqué ce sujet comme résolu.

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

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…

+0 -0

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?

+0 -0

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

+0 -0

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

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?

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.

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

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.

+0 -0

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

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).

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)

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

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