Seltsamer Migrationsfehler in Tests während GH workflow

Ich versuche, eine Fremdschlüsselbeziehung mit der Topics-Tabelle zu erstellen.

Das Problem ist, dass sie in der GitHub Workflow-Testumgebung aus seltsamsten Gründen während der Tests fehlschlägt. Sie versucht, auf ein Feld aus der übergeordneten Tabelle zuzugreifen, das nicht mehr existiert und vor Jahren in einer Kernmigration entfernt wurde!

Der Fehler lautet PG::UndefinedColumn: ERROR: column topics.off_topic_count does not exist

Nun ja, weil es in einer Kernmigration im Jahr 2018 entfernt wurde!

Ich habe bestätigt, dass dies während des Testprozesses bereits ausgeführt wurde:

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

Ich beziehe dieses alte Feld der übergeordneten Tabelle in keiner Weise explizit … es scheint die SQL-Abfrage selbst zu generieren … aber unangemessen für die aktuelle Definition der Dinge.

== 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"...

Die Tabellendefinition ist wirklich einfach:

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

Das noch seltsamere ist, dass diese Migration in der Produktion funktioniert!

Jede Einsicht ist sehr willkommen!

1 „Gefällt mir“

Oh, ich wurde dafür gut von RUBOCOPPED :policeman: :police_car:

Offenses:

db/migrate/20231119010101_create_locations_topic_table.rb:6:7: C: Discourse/NoAddReferenceOrAliasesActiveRecordMigration: AR-Methoden add_reference, add_belongs_to, t.references und t.belongs_to sind
riskant für große Tabellen und haben zu viele Hintergrund-Magieoperationen.
Schreiben Sie stattdessen eine disable_ddl_transactions! Migration und schreiben Sie benutzerdefiniertes SQL, um
die neue Spalte und CREATE INDEX CONCURRENTLY hinzuzufügen. Verwenden Sie die Klausel IF NOT EXISTS,
um die Migration wiederholbar zu machen, wenn sie teilweise fehlschlägt.

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

Nun, das könnte ein Teil des Problems sein.
Zu viel :magic_wand: im Spiel, das ist das Problem!
Man lernt nie aus! :mortar_board:

1 „Gefällt mir“

Der Rubocop-Hinweis ist gut, aber ich glaube nicht, dass er die Ursache für diesen Fehler ist. (Das von ihm erwähnte „Risiko“ bezieht sich auf Sperren in Tabellen mit hohem Datenverkehr, die sich auf den Produktionsverkehr auswirken würden. Also nichts, was Fehler in einer Testumgebung verursachen würde)

Sie können wahrscheinlich denselben Fehler lokal reproduzieren, indem Sie RAILS_ENV=test bin/rake db:drop db:create db:migrate ausführen (d. h. eine Datenbank von Grund auf neu migrieren, mit aktiviertem Locations-Plugin)

Ich vermute, das Problem ist, dass Sie Rake-Aufgaben innerhalb einer Migration aufrufen. Im Kern vermeiden wir es generell, jeglichen Anwendungscode in Migrationen auszuführen, da dies seltsame Nebenwirkungen haben kann. Am besten bleiben Sie bei reinem SQL.

In diesem Fall gehe ich davon aus, dass der ActiveRecord-Schema-Cache früh in den Migrationen gefüllt wird (wenn topics.off_topic_count noch existiert). Wenn dann Ihre Rake-Aufgabe ausgeführt wird, läuft sie mit einem alten Schema-Cache und ActiveRecord versucht, Spalten zu laden, die nicht mehr existieren.

Sie können dies wahrscheinlich abmildern, indem Sie ActiveRecord::Base.clear_cache! hinzufügen, bevor Sie die Rake-Aufgaben aufrufen … aber betrachten Sie dies nicht als Empfehlung :wink:. Am besten wäre es, den Aufruf der Rake-Aufgaben ganz zu vermeiden. Wenn Sie etwas in der Datenbank manipulieren müssen, verwenden Sie reines SQL innerhalb der Migration.

2 „Gefällt mir“

Danke David, ich werde es in eine SQL-Anweisung verschieben und sehen, ob das … löst.

Das hat funktioniert, danke David!

2 „Gefällt mir“

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