Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

269
Visualizações
Rails / MySQL: ¿Cómo consultar un registro por su marca de tiempo completa 'created_at'?

Quiero poder encontrar un registro de User por su marca de tiempo created_at (que en este caso es: 2020-08-07 11:30:28.5934908 ).

Pero el resultado es este:

 User.where(created_at: '2020-08-07 11:30:28.5934908').first => nil

La razón por la que este registro de usuario (existente) no se encuentra parece hacerse evidente en la consulta de MySQL que generó Rails:

User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`created_at` = '2020-08-07 11:30:28.593490' ORDER BY `users`.`id` ASC LIMIT 1

... donde, por alguna razón, el último dígito 8 se elimina de la marca de tiempo 2020-08-07 11:30:28.5934908 utilizada en la consulta MySQL.

¿Cuál es el problema aquí? ¿Rails acorta la marca de tiempo en la consulta? ¿O MySQL hace esto? ¿Cómo puedo solucionar esto?

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Según sus comentarios, creo que el principal problema está en la conversión del tiempo preciso en microsegundos a Float. Float (aunque en Ruby internamente es un Double) no tiene suficiente precisión para representar completamente todas las fechas/horas con una precisión de microsegundos, como se documenta en la clase Time (aunque curiosamente hablan de "nanosegundos"). Tal conversión solo intenta encontrar la representación más cercana posible en Float. Redondear el número flotante resultante a 6 dígitos puede funcionar, pero no estoy seguro de que funcione siempre...

Suponga que el tiempo real almacenado en DB es 2020-08-07 11:30:28.593491 . Como habrás notado, esto se convierte en Float de forma imprecisa:

 >> Time.parse('2020-08-07 11:30:28.593491').to_f => 1596792628.5934908

El método garantizado sería utilizar un número racional en su lugar, es decir, to_r :

 >> Time.parse('2020-08-07 11:30:28.593491').to_r => (1596792628593491/1000000)

Para reconstruir el Tiempo a partir del número racional, puede usar Time.at :

 >> Time.at(Rational(1596792628593491, 1000000)).usec => 593491

Tenga en cuenta que los microsegundos se conservan completamente aquí.

Por lo tanto, almacenar un created_at time con precisión y usarlo más tarde para buscar un registro implica usar una variable de número racional en lugar de Float:

 >> user_created_at = User.first.created_at.to_r => (1596792628593491/1000000) >> User.where(created_at: Time.at(user_created_at)).first == User.first => true

Un enfoque alternativo podría ser almacenar los segundos enteros desde Epoch ( User.first.created_at.to_i ) y la fracción de nanosegundos ( User.first.created_at.usec ) por separado en dos variables. También se pueden usar en Time.at para reconstruir el tiempo atrás.

Como nota al margen, esto también se ha discutido en una edición de Rails con una conclusión similar.

over 4 years ago · Santiago Trujillo Relatório

0

Esta no es una respuesta directa a su pregunta, sino una especie de solución. Podría consultar la columna created_at en un delta de tiempo muy pequeño como este.

 User.where(created_at: '2020-08-07 11:30:28.593490'...'2020-08-07 11:30:28.593491')
over 4 years ago · Santiago Trujillo Relatório

0

Según el comentario de @BoraMa (¡gracias!), MySQL created_at timestamp debe tener solo 6 dígitos. Por lo tanto, la consulta de trabajo se vería así:

 User.where(created_at: '2020-08-07 11:30:28.5934908'.round(6)).first
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda