Bonjour,
Je tente de passer un code qui fonctionnait bien sous 2.7 vers py 3.6 (je suis en cours de migration complète entre 2.7 et 3.x
J'ai créé un module de connexion à notre SQL2008, pour passer les commandes SQL : MonModuleSQL.py.
J'appel ce module dans les scripts où j'en ai besoin.
dans mon cas actuel, dans MonModuleSQL, j'ai la définition suivante:
Si je fais un test, en restant dans ce MonModuleSQL.py(en bas du module), j'excute mon code suivant, ça passe sans soucis.
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 # -*- coding: utf-8 -*- import pyodbc def select_MSSQL(select_MS): """ Connexion au serveur MSSQL passage de la commande SQL select en parametre renvoi la liste""" server = 'MON_SQL' database = 'data' username = "sa" password = 'Pword' param_connect = ('DRIVER={SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+password+";") cnxn = pyodbc.connect(param_connect) # connexion a SQL # cnxn.setencoding(str, encoding='cp1252') # Necessaire en 2.7, mais visiblement non connu en 3.9 cursor = cnxn.cursor()#cursor pour passage des commandes suivantes cursor.execute(select_MS) #execute la requete SQL rows = cursor.fetchall() cnxn.commit() #fermeture connexion return rows
résultat OK
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 reference,id = 'A260', 'ID2001' Rq_SQL ="""SELECT SUBSTRING(data.dbo.Table1.Date_crea,3,2), CAST({fn DAYOFYEAR(data.dbo.Table1.Date_crea)} AS varchar(3)), data.dbo.Table1.nom, data.dbo.Table1.libelle, data.dbo.Table1.memo, data.dbo.Table2.identifiant FROM**data.dbo.Table2 INNER JOIN data.dbo.Table2 AS Table2_1 ON data.dbo.Table2.dossier = Table2_1.source INNER JOIN data.dbo.Table1 ON Table2_1.dossier = data.dbo.Table1.dossier WHERE (data.dbo.Table1.ref = '%s') AND (data.dbo.Table2.identifiant='%s')"""%(reference,id) retour_MSSQL = select_MSSQL(Rq_SQL) print r(etour_MSSQL)
Par contre, lorsque j'appel cette définition depuis un autre script.
où j'ai des boucles qui déterminent les valeurs utilisées en where, et reprosuisent ma commande SQL:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 # -*- coding: utf-8 -*- sys.path.append(r"\\SRV_FICHIERS\...\MonModuleSQL.py") import MonModuleSQL as odbc
puis j'appel ma définition odbc.select_MSSQL:
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 # -*- coding: utf-8 -*- [sys.path.append...] [...] reference = liste[0] id = liste[1] [...] Rq_SQL ="""SELECT SUBSTRING(data.dbo.Table1.Date_crea,3,2), CAST({fn DAYOFYEAR(data.dbo.Table1.Date_crea)} AS varchar(3)), data.dbo.Table1.nom, data.dbo.Table1.libelle, data.dbo.Table1.memo, data.dbo.Table2.identifiant FROM**data.dbo.Table2 INNER JOIN data.dbo.Table2 AS Table2_1 ON data.dbo.Table2.dossier = Table2_1.source INNER JOIN data.dbo.Table1 ON Table2_1.dossier = data.dbo.Table1.dossier WHERE (data.dbo.Table1.ref = '%s') AND (data.dbo.Table2.identifiant='%s')"""%(reference,id)
J'ai le message d'erreur suivant:
Code : Sélectionner tout - Visualiser dans une fenêtre à part retour_MSSQL =odfbe.select_MSSQL(Rq_SQL)
File "\\SRV_FICHIERS\...\MonModuleSQL.py", line 138, in select_MSSQL
cursor.execute(select_MS) #execute la requete SQL
ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Syntaxe incorrecte vers '\xa0'. (102) (SQLExecDirectW)")
'\xa0' correspond aux espaces dans le texte, c'est bien cela?
J'ai donc un problème d'encodage lors de l’envoie de ma requête SQL en string , vers le module appelé en externe (puisque la ma requête passe bien, lorsque qu'elle est exécuter en directe dans le module externe).
J'ai tenté pas mal de chose:
- Rq_SQL =u"""SELECT SUBSTRING(...
- Rq_SQL.encode("CP1252")
et je ne sais plus, tellement j'ai fait de tests...
Mais rien n'y fait... ma commande SQL arrive mal encodé dans mon module SQL.
Quelqu'un verrait-il une piste svp?
Merci
Partager