Extraño error de migración en las pruebas durante el flujo de trabajo de GH

Estoy intentando crear una relación de clave externa con la tabla Topics.

El problema es que falla en el entorno de prueba del flujo de trabajo de GitHub durante las pruebas por una razón extraña: está intentando acceder a un campo de la tabla principal que ya no existe y que se eliminó en una migración principal hace años.

El error es PG::UndefinedColumn: ERROR: column topics.off_topic_count does not exist

Pues sí, porque se eliminó en una migración principal en 2018!

He confirmado que esto ya se ejecutó durante el proceso de prueba:

== 20180917024729 RemoveSuperfluousColumns: migrating =========================
== 20180917024729 RemoveSuperfluousColumns: migrated (0.0410s) ===============

No estoy haciendo referencia explícita a este antiguo campo de la tabla principal… parece que está generando el SQL por sí mismo… pero de forma inapropiada para la definición actual de las cosas.

== 20231119010101 CreateLocationsTopicTable: migrating ========================rake aborted!

[12035](https://github.com/paviliondev/discourse-locations/actions/runs/7039607316/job/19158951878?pr=103#step:19:12036)StandardError: An error has occurred, this and all later migrations canceled: (StandardError)

[12036](https://github.com/paviliondev/discourse-locations/actions/runs/7039607316/job/19158951878?pr=103#step:19:12037)

[12037](https://github.com/paviliondev/discourse-locations/actions/runs/7039607316/job/19158951878?pr=103#step:19:12038)PG::UndefinedColumn: ERROR: column topics.off_topic_count does not exist

[12038](https://github.com/paviliondev/discourse-locations/actions/runs/7039607316/job/19158951878?pr=103#step:19:12039)LINE 1: ...cs"."deleted_at", "topics"."highest_post_number", "topics"...

La definición de la tabla es muy simple:

class CreateLocationsTopicTable < ActiveRecord::Migration[7.0]
  def change
    create_table :locations_topic do |t|
      t.references :topic, foreign_key: true
      t.float :latitude, null: false

SNIP

Lo más extraño es que esta migración ¡funciona en Producción!

¡Cualquier información es bienvenida!

1 me gusta

Me han aplicado la regla RUBOCOPPED para esto :policeman: :police_car:

Ofensas:

db/migrate/20231119010101_create_locations_topic_table.rb:6:7: C: Discourse/NoAddReferenceOrAliasesActiveRecordMigration: Los métodos AR add_reference, add_belongs_to, t.references y t.belongs_to son de alto riesgo para tablas grandes y tienen demasiadas operaciones mágicas en segundo plano.
En su lugar, escriba una migración disable_ddl_transactions! y escriba SQL personalizado para agregar la nueva columna y CREATE INDEX CONCURRENTLY. Utilice la cláusula IF NOT EXISTS para que la migración se pueda volver a ejecutar si falla a mitad de camino.

      t.references :topic, foreign_key: true
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Ahora eso podría ser parte del problema.

¡Demasiada :magic_wand: en juego, ese es el problema!

Se aprende y se vive. :mortar_board:

1 me gusta

El consejo de Rubocop es bueno, pero no creo que sea la causa de este error. (el ‘riesgo’ que menciona se refiere a bloqueos en tablas de alto tráfico que afectarían el tráfico de producción. Así que no es algo que cause errores en un entorno de prueba)

Probablemente puedas reproducir el mismo error localmente ejecutando RAILS_ENV=test bin/rake db:drop db:create db:migrate (es decir, migrando una base de datos totalmente desde cero, con el plugin de ubicaciones habilitado)

Sospecho que el problema es que estás invocando tareas Rake dentro de una migración. En el núcleo, generalmente evitamos ejecutar cualquier tipo de código de aplicación en las migraciones debido a los extraños efectos secundarios que pueden ocurrir. Es mejor ceñirse a SQL puro.

En este caso, mi suposición es que la caché del esquema de ActiveRecord se está poblando al principio de las migraciones (cuando topics.off_topic_count todavía existe). Luego, cuando tu tarea Rake se ejecuta, lo hace con una caché de esquema antigua y, por lo tanto, ActiveRecord intenta cargar columnas que ya no existen.

Probablemente puedas mitigar esto agregando ActiveRecord::Base.clear_cache! antes de invocar las tareas Rake… pero no lo tomes como una recomendación :wink:. Lo mejor sería evitar invocar las tareas Rake por completo. Si necesitas manipular algo en la base de datos, usa SQL puro dentro de la migración.

2 Me gusta

Gracias David, lo moveré a una declaración SQL y veré si eso lo resuelve…

¡Eso lo solucionó, gracias David!

2 Me gusta

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.