microsoft conectar con python ms-access pypyodbc

python - conectar - Problema de consulta de la base de datos de Access: "no se pudo convertir cadena en flotante: E+6"



python microsoft access (2)

Tengo una base de datos en MS Access. Estoy intentando consultar una tabla a Python usando pypyodbc. Aparece el siguiente mensaje de error:

ValueError: no se pudo convertir cadena en flotante: E + 6

Los números en la tabla son bastante grandes, con hasta diez cifras significativas. El mensaje de error me dice que MSAccess está formateándolos en notación científica y Python los está leyendo como cadenas.

Los campos de la tabla están formateados como singles con dos decimales. Cuando veo los números en la tabla en la base de datos no están formateados usando notación científica. pero el mensaje de error parece indicar que lo son.

Además, si cambio los números en la tabla (al menos para una fila de prueba) a números pequeños (números enteros del 1 al 5) se ejecuta la consulta. Lo cual respalda mi teoría de que el problema es el formateo científico de un gran número.

Alguna idea de cómo:

  1. escribir en la tabla de la base de datos de forma que los números no estén formateados en notación científica, o
  2. hacer que pypyodbc recupere los números como tales e ignore cualquier notación científica.

Mientras preparaba los archivos de prueba para que intente reproducirlos, noté que dos de los campos de la tabla estaban configurados en Tipo individual en lugar de Doble. Los cambió a Double y eso resolvió el problema. Perdón por la molestia y gracias por la ayuda.


Esto parece ser un problema de compatibilidad entre pypyodbc y el controlador Access ODBC al recuperar números "grandes" o "pequeños" de un campo Single o Double (columna), donde "grande" significa

  • Valores Single con más de 6 dígitos significativos a la izquierda del punto decimal, o
  • Valores Double con más de 14 dígitos significativos a la izquierda del punto decimal

y "pequeño" significa

  • Valores Single con más de 6 ceros inmediatamente a la derecha del punto decimal, o
  • Valores Double con más de 14 ceros inmediatamente a la derecha del punto decimal

cuando los números se representan como decimales "normales" (es decir, no en notación científica).

Código para recrear

import pypyodbc cnxn = pypyodbc.connect( r"DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};" r"DBQ=C:/Users/Public/Database1.accdb") crsr = cnxn.cursor() try: crsr.execute("DROP TABLE tblJunk") except pypyodbc.ProgrammingError as pe: # ignore "table does not exist" if pe.value[0] != ''42S02'': raise crsr.execute("CREATE TABLE tblJunk (ID INT PRIMARY KEY, DoubleField DOUBLE, SingleField SINGLE)") crsr.execute("INSERT INTO tblJunk (ID, DoubleField) VALUES (1, 12345678.9)") crsr.execute("SELECT DoubleField, SingleField FROM tblJunk WHERE ID=1") row = crsr.fetchone() print(row) # prints: (12345678.9, None) crsr.execute("UPDATE tblJunk SET SingleField = DoubleField WHERE ID=1") crsr.execute("SELECT DoubleField, SingleField FROM tblJunk WHERE ID=1") row = crsr.fetchone() # ValueError: could not convert string to float: E+7

Solución 1: para valores Single , el uso de la función CDbl() puede evitar el error:

crsr.execute("SELECT DoubleField, CDbl(SingleField) AS foo FROM tblJunk WHERE ID=1") row = crsr.fetchone() print(row) # prints: (12345678.9, 12345679.0)

Solución 2: use la función CStr() para devolver el valor como una cadena y luego conviértalo en un flotante (funciona tanto para Single como para Double ):

crsr.execute("SELECT DoubleField, CStr(SingleField) AS foo FROM tblJunk WHERE ID=1") row = crsr.fetchone() print(row) # prints: (12345678.9, u''1.234568E+07'') print(float(row[1])) # prints: 12345680.0

Solución 3: use pyodbc en lugar de pypyodbc.