SqlAlchemy mysql milisegundos o microsegundos de precisión

He estado aventurándome en la odisea de intentar que la resolución de tiempo fraccional funcione correctamente en mi base de datos. Uso el método de python datetime.now() para crear objetos de fecha. Luego almaceno estos objetos en un campo que se asigna a una COLUMN(DATETIME(9)) que es de la biblioteca de SqlAlchemy. Originalmente, recibía el error de que mis datos estaban siendo truncados. Esto es porque estaba usando mysql 5.5. Desde entonces, he actualizado a 5.6.19 y ya no recibo el error de datos truncados.

Sin embargo, la base de datos todavía no contiene realmente entradas de tiempo fraccionarias. Por ejemplo, aquí está el valor de cuando se crea una instancia del objeto datetime.now ():

 2015-04-17 16:31:12.804444 

Lo anterior es exactamente lo que esperaría. El objeto en memoria tiene una resolución de microsegundos. Ahora, después de guardar esto en la base de datos mysql, veo el siguiente valor si abro el cliente de línea de comandos mysql y devuelvo la fila con una statement de selección:

 2015-04-17 16:31:13 

Obviamente, el valor se redondea al segundo más cercano. ¡Esto es malo, y no tengo idea de qué lo está causando!

En caso de que sea relevante, estoy usando mysql-connector-python == 2.0.3

ACTUALIZACIÓN: También intenté usar COLUMN(DATETIME(6)) , pero tuve el mismo comportamiento.

Estoy abajo incluyendo el modelo, en caso de que la información sea relevante:

 class User(Base): __tablename__ = 'Users' uid = Column(INT, primary_key=True, autoincrement=True) dateCreated = Column(DATETIME(6)) def __init__(self, *args, **kwargs): super(user, self).__init__(*args, **kwargs) self.dateCreated = datetime.now() 

ACTUALIZACIÓN: la sugerencia de Pedro no fue el problema, aunque definitivamente me ayudó a progresar, así que muchas gracias. Intenté pasar por el código en el conector SQL hasta que llegué a la statement de inserción mysql. La statement de hecho contiene el valor de tiempo fraccionario. Sin embargo, cuando se ejecuta, el valor se redondea. Cuando hice una descripción en la tabla, noté que el tipo de fecha y hora es solo eso, datetime y datetime cuando realmente debería ser datetime(6) .

Estoy generando la base de datos utilizando el modelo SA, que declara explícitamente la Column(DATETIME(6)) , y Base.metadata.create_all(self.db, checkfirst=True) , por lo que no entiendo por qué (6) no está terminando en la estructura de la tabla real. Aunque creo que lo resolveré en breve, y publicaré una actualización cuando lo haga.

ACTUALIZACIÓN: El constructor a DATETIME no acepta la especificación de longitud de campo. Solo se necesita un argumento para las zonas horarias. No me queda claro cómo especificar la longitud de un campo de fecha y hora, ya que para tipos como varchar, solo se lo pasaría al constructor. La inmersión continúa.

El problema que estaba teniendo es que la clase DATETIME de SqlAlchemy de stock no funciona con el requisito de mysql de pasar un valor (6) al constructor para representar valores de tiempo fraccional. En su lugar, uno necesita usar la clase sqlalchemy.dialects.mysql.DATETIME . Esta clase permite el uso del parámetro fsp (parámetro de fracción de segundos). Por lo tanto, una statement de columna debería tener el siguiente aspecto:

 dateCreated = Column(DATETIME(fsp=6)) 

Gracias a los otros que respondieron. Ayudó a guiar mi investigación para finalmente tropezar con esta distinción esotérica y muy confusa.

Esto parece ser un problema abierto con MySQLdb, no MySQL o SQLAlchemy.

http://sourceforge.net/p/mysql-python/feature-requests/24/

Puede intentar usar otra biblioteca de controladores MySQL (consulte la documentación de SQLAlchemy para conocer las opciones compatibles), o puede probar el monkeypatch que se sugiere en el tema abierto.

Según la documentación de MySQL , solo admite la precisión de hasta 6 lugares (microsegundos):

“MySQL 5.6.4 y versiones posteriores amplían el soporte fraccional de segundos para los valores de TIME, DATETIME y TIMESTAMP, con una precisión de hasta microsegundos (6 dígitos)”

No lo sé con seguridad, pero la especificación de 9 dígitos podría revertir la columna a una precisión predeterminada más pequeña.