IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

PyODBC, migration de 2.7 en 3.9, nouveau format Decimal()


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Géomaticien (plutôt sur Arcgis...)
    Inscrit en
    Juillet 2013
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Géomaticien (plutôt sur Arcgis...)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juillet 2013
    Messages : 49
    Par défaut PyODBC, migration de 2.7 en 3.9, nouveau format Decimal()
    Bonjour à tous,

    Je suis en train de migré un script que javais en 2.7 vers du python 3.9. Notamment une requête sur serveur MSSQL, via PyODBC.
    Sans rien changer sur les éléments de connexion et le passage de mon SELECT, le code se passe bien, j'ai toutes mes lignes.

    Ma question est sur le format des valeurs retournées, d'un champ où notre ERP inscrit une surface en hectare, champ numérique de type ; surface(decimal(18,8),NULL).
    Sous python 2.7, le résultat remonté était directement utilisable ex; 13.8196.
    En python 3.9, le résultat est tout autre, au lieu de 13.8196, je me retrouve avec ; Decimal('1381960000').
    Quelqu'un saurait-il m'expliquer pourquoi ce résultat, svp? Je ne trouve rien d'assez claire pour moi sur les forums. SQL connait le format de ma cellule, pourquoi est-ce que j'obtiens une "traduction" de la valeur et pas directement la valeur utilisable?

    Comment puis-je déterminer que Decimal('1381960000') = 13.8196 et non pas 138.196 ou 1.38196, en hectare ça n'a pas la même incidence

    Merci de votre aide.
    Cordialement

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 851
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Ton histoire me rappelle celle du crash du vol Varig 254 (1989). Le plan de vol indiquait "cap 0270" mais c'était une nouvelle notation à 4 chiffres avec le 4° qui indiquait la décimale (027.0) pour des avions nouveau modèle avec pilote automatique à décimales. Mais le "point" n'était pas mentionné sur le plan de vol.
    Le commandant était absent quand le truc a été sorti et en plus son pilote automatique était ancien modèle à 3 chiffres. Il a donc saisi "270". L'avion est parti vers l'ouest au lieu de partir au nord et a fini par tomber à court de carburant. Donc en effet le point est important => https://fr.wikipedia.org/wiki/Vol_Varig_254

    Malheureusement ta description est encore trop floue et amène trop de possibilités. Par exemple ton PyODBC est-il à jour?

    On peut quand-même s'en sortir avec du bricolage. Par exemple decimal(18, 8) signifie "18 chiffres dont 8 après la virgule". Si on applique à ton résultat "1381960000" on remonte 8 chiffres et ça donne bien "13.81960000". Mais soit c'est un comportement voulu et dans ce cas à toi de remonter les 8 chiffres, soit c'est involontaire (bug? version?) et donc ça devient du bricolage.

    Ce que je sais, c'est que le module decimal de P2 fonctionne à l'identique sous P3 (rien à modifier contrairement à d'autres comme par exemple ConfigParser qui a changé de nom entre P2 et P3).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 778
    Par défaut
    Salut,

    Un tel comportement s'appelle "bug" et semble déjà répertorié vs PyODBC (avec une solution à tester).
    note: chercher sur Internet prend juste quelques secondes...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Membre averti
    Homme Profil pro
    Géomaticien (plutôt sur Arcgis...)
    Inscrit en
    Juillet 2013
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Géomaticien (plutôt sur Arcgis...)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juillet 2013
    Messages : 49
    Par défaut
    Merci

    Sve@r, bon ça va être du bricolage
    Pardon Wiztricks, je ne maitrise ni le développement (je suis forestier à la base...), ni l'anglais pour trouver et comprendre ce type de post. Je me reste sur les forums français...

    Bonne journée

  5. #5
    Membre averti
    Homme Profil pro
    Géomaticien (plutôt sur Arcgis...)
    Inscrit en
    Juillet 2013
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Géomaticien (plutôt sur Arcgis...)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juillet 2013
    Messages : 49
    Par défaut
    Ah, j'ai oublié, ma version PyODBC, la 4.0.32.

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 851
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par little_kevin Voir le message
    Sve@r, bon ça va être du bricolage
    D'autant plus que wiztricks a remonté l'info que c'était un bug.
    Pour essayer de "pérenniser" ce bricolage, tu peux voir si l'info "decimal(18, 8)" est disponible depuis PyODBC. J'ai dans l'idée que ça devrait l'être car j'ai écrit des programmes lisant une bdd Postgres pour remonter sa structure en modèle et j'ai eu le même souci (trouver le format d'un champ numérique). Donc comme une bdd se décrit elle-même, il doit y avoir qqpart un truc qui dit "ce champ est decimal(x, y)". Ainsi ton bricolage s'adapterait automatiquement au format du champ traité.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 778
    Par défaut
    Citation Envoyé par little_kevin Voir le message
    Comment puis-je déterminer que Decimal('1381960000') = 13.8196 et non pas 138.196 ou 1.38196, en hectare ça n'a pas la même incidence
    Si le champ est decimal(18,8), ça veut dire une précision de 18 (chiffres significatif) et une échelle de 8.
    Donc, je multiplie 1381960000 par 10-8 et j'obtiens 13.8196.

    Pour les contournements proposés dans le bug report, essayez d'ajouter l'instruction pyodbc.setDecimalSeparator('.') juste après l'import de pyodbc... mais je n'ai pas testé.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Membre averti
    Homme Profil pro
    Géomaticien (plutôt sur Arcgis...)
    Inscrit en
    Juillet 2013
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Géomaticien (plutôt sur Arcgis...)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juillet 2013
    Messages : 49
    Par défaut
    Citation Envoyé par wiztricks Voir le message

    Pour les contournements proposés dans le bug report, essayez d'ajouter l'instruction pyodbc.setDecimalSeparator('.') juste après l'import de pyodbc... mais je n'ai pas testé.

    - W
    Avec l'instruction que tu cites, j'obtiens Decimal('13.91860000') au lieu de Decimal('1391860000'), ce qui est déjà plus parlant. Et j'ai également testé dans mon expression
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select cast(Surface as float) from...
    et mon résultat est directement 13.9186 (avec ou sans cette nouvelle instruction).

    Il faut que cela tienne 1 an avant de passer de SQL2008R2 à un nouveau SQL Server, nouvelle infra SI...etc. On reverra à ce moment là.

    Encore merci de m'avoir fait progresser.

  9. #9
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 778
    Par défaut
    Citation Envoyé par little_kevin Voir le message
    Et j'ai également testé dans mon expression
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select cast(Surface as float) from...
    et mon résultat est directement 13.9186 (avec ou sans cette nouvelle instruction).
    L'avantage de Decimal est de ne pas avoir l'imprécision des floats côté arrondis... ce qui peut être important pour certaines mesures (la monnaie, les surfaces cadastrales,...).
    Je ne sais pas dans quel contexte vous récupérez Decimal('13.91860000'), mais c'est la représentation d'un nombre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> from decimal import Decimal
    >>> d = Decimal('13.91860000')
    >>> d   # affiche le "repr"
    Decimal('13.91860000')
    >>> print(d)   # affiche le "str"
    13.91860000
    >>> d - 13
    Decimal('0.91860000')
    >>> d - 13 > 0
    True
    >>>
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  10. #10
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 851
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par little_kevin Voir le message
    Et j'ai également testé dans mon expression
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select cast(Surface as float) from...
    et mon résultat est directement 13.9186 (avec ou sans cette nouvelle instruction).
    Super dangereux ça !!!
    Le float est par nature imprécis. Ce n'est pas la faute de Python mais la façon dont sont convertis les nombres décimaux en binaire dans un processeur (somme de puissances négatives de 2). Si parfois ça marche (0.625 = 2^-1 + 2^-3), pour la majorité des cas cela ne marche pas parfaitement (0.6 par exemple ne peut pas être écrit sous la forme d'une somme de puissances négatives entières de 2).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> 0.6/3
    0.19999999999999998
    >>> 0.2*3
    0.6000000000000001
    >>>
    Après il y a beaucoup de situations où ça ne gêne personne. La vitesse de la lumière est de 299792,458 km/s mais si on prend 300000, sauf pour une minorité de nimbus à lunettes qui cherchent jusqu'où vont les galaxies au millimètre près, pour les autres ça va tout aussi bien.
    Mais il y a aussi beaucoup de situations où ça gênera. Si tous les mois tu perds 1cts sur tes comptes du fait de l'erreur d'arrondi ça va pas te tuer mais à mon avis ça va bien te faire ch...

    Donc tout dépend de l'usage que tu fais de ta valeur récupérée.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  11. #11
    Membre averti
    Homme Profil pro
    Géomaticien (plutôt sur Arcgis...)
    Inscrit en
    Juillet 2013
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Géomaticien (plutôt sur Arcgis...)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juillet 2013
    Messages : 49
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Super dangereux ça !!!
    Le float est par nature imprécis. Ce n'est pas la faute de Python mais la façon dont sont convertis les nombres décimaux en binaire dans un processeur...
    Ah OK . Merci

Discussions similaires

  1. [WS 2008 R2] Migration des droits de dossiers dans un nouveau Ws
    Par taz devil dans le forum Windows Serveur
    Réponses: 0
    Dernier message: 01/09/2015, 21h03
  2. Migration de serveur SQL SERVER 2005 au nouveau domaine AD
    Par lbh85 dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 11/07/2012, 12h44
  3. Réponses: 4
    Dernier message: 12/10/2009, 18h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo