Pyodbc passage de Py2.7 vers Py3.6, pb encodage entre module
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:
Code:
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 |
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:
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) |
résultat OK
Par contre, lorsque j'appel cette définition depuis un autre script.
Code:
1 2 3 4
|
# -*- coding: utf-8 -*-
sys.path.append(r"\\SRV_FICHIERS\...\MonModuleSQL.py")
import MonModuleSQL as odbc |
où j'ai des boucles qui déterminent les valeurs utilisées en where, et reprosuisent ma commande SQL:
Code:
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) |
puis j'appel ma définition odbc.select_MSSQL:
Code:
retour_MSSQL =odfbe.select_MSSQL(Rq_SQL)
J'ai le message d'erreur suivant:
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