PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Warum fügt Rails 5 die nextval-Methode in die Schemadatei ein?

Dies ist eine etwas lange Antwort, daher habe ich sie in Abschnitte unterteilt. Anschnallen!

Meine Theorie

Meine Vermutung ist, dass Ihre Entwicklungsdatenbank das tut die lessons_id_seq enthalten Sequenz, und dass seine Definition von flightlessons.id ist so eingestellt, dass es davon abhängt (d. h. genau das, was Rails in Ihre Schemadatei einfügt).

Wie und warum? Wahrscheinlich haben Sie die lessons umbenannt Tabelle zu flightlessons irgendwann in der Vergangenheit, aber diese Umbenennung änderte nichts an der Reihenfolge, von der die Tabelle abhing -- und seit schema.rb tut nicht Aufzeichnungssequenzen, die lessons_id_seq Die Sequenz wird nicht in Ihre Testdatenbank kopiert, und daher erhalten Sie diesen Fehler.

Um meine Theorie zu überprüfen, führen Sie rails db aus und versuchen Sie die folgenden Befehle:

\d lessons_id_seq

Dies sollte die Definition dieser Sequenz zurückgeben. Versuchen Sie dann:

\d flightlessons

Und schauen Sie sich die Definition der id an Säule. Ich erwarte, dass es DEFAULT nextval('lessons_id_seq') enthält .

Korrekturen

Der einfachste Weg, dies zu beheben, besteht darin, zur Verwendung von structure.sql zu wechseln statt schema.rb (Siehe die Dokumentation ). Dadurch wird der genaue Zustand Ihrer Datenbank übertragen und jegliche Interferenz oder Interpretation durch Rails vermieden, was Ihr aktuelles Problem verursacht. Ich empfehle immer structure.sql für Produktionssysteme.

Sie können jedoch auch in Ihre Entwicklungsdatenbank gehen und den Sequenznamen ändern:

ALTER SEQUENCE lessons_id_seq RENAME TO flightlessons_id_seq;
ALTER TABLE flightlessons ALTER COLUMN id SET DEFAULT nextval('flightlessons_id_seq');

Dies wäre eine schreckliche Idee auf einem Produktionssystem, aber wenn Ihr Problem nur lokal ist, sollte es Ihren aktuellen Datenbankstatus mit Ihrem schema.rb korrigieren und adressieren Sie damit Ihr aktuelles Problem. Möglicherweise möchten Sie dies in eine Migration codieren, wenn Sie rails db:drop db:create db:migrate möchten um an einer neuen App zu arbeiten.

Warum jetzt?

Das Verhalten, bei dem Rails den default ausgibt Der Wert für den Primärschlüssel Ihrer Tabelle kann sehr wohl neu in Rails 5 sein. Zuvor hat Rails möglicherweise einfach darauf vertraut, dass Ihre ID-Spalte einen vernünftigen Standardwert hatte, und jeden Wert ignoriert, den es tatsächlich gesehen hat. Aber ich habe nicht nachgeforscht, ob das stimmt oder nicht.