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:
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.
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.
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:
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:
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
Partager