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 : 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
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
 
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 : 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
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
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 : Sélectionner tout - Visualiser dans une fenêtre à part
 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