Überprüfen Sie, ob in Rails eine Tabelle vorhanden ist


174

Ich habe eine Rechenaufgabe, die nur funktioniert, wenn eine Tabelle vorhanden ist. Ich arbeite mit mehr als 20 Ingenieuren an einer Website, daher möchte ich sicherstellen, dass sie die Tabelle migriert haben, bevor sie eine Rechenaufgabe ausführen können, die die jeweilige Tabelle auffüllt.

Hat AR eine Methode wie Table.exists? Wie kann ich sicherstellen, dass die Tabelle erfolgreich migriert wurde?


12
Der Witz geht .. wie viele Ingenieure braucht es, um eine Tabelle zu migrieren :)
Zabba

1
Bei der Produktion 1. Bei der Inszenierung von Dutzenden und jeweils mehrmals.
Thenengah

2
Wäre es nicht einfacher, die Migrationen einfach zu Beginn Ihrer Rake-Aufgabe auszuführen? Sie müssen sich also keine Sorgen über fehlende Tabellen machen.
Raskhadafi

@raskhadafi: Beachten Sie, dass fehlende Tabellen zu Problemen führen, wenn Ihre Konfigurations- / Initialisierer sie verwenden. (dh wird sogar rake db:migratescheitern.)
ocodo

Antworten:


302

In Rails 5 wurde die API in Bezug auf Tabellen / Ansichten und Datenquellen explizit .

# Tables and views
ActiveRecord::Base.connection.data_sources
ActiveRecord::Base.connection.data_source_exists? 'kittens'

# Tables
ActiveRecord::Base.connection.tables
ActiveRecord::Base.connection.table_exists? 'kittens'

# Views
ActiveRecord::Base.connection.views
ActiveRecord::Base.connection.view_exists? 'kittens'

In Rails 2, 3 und 4 handelt es sich bei der API um Tabellen .

# Listing of all tables and views
ActiveRecord::Base.connection.tables

# Checks for existence of kittens table/view (Kitten model)
ActiveRecord::Base.connection.table_exists? 'kittens'

Abrufen des Status von Migrationen:

# Tells you all migrations run
ActiveRecord::Migrator.get_all_versions

# Tells you the current schema version
ActiveRecord::Migrator.current_version

Wenn Sie weitere APIs für Migrationen oder Metadaten benötigen, siehe:


4
ActiveRecord::Base.connection.table_exist 'users'würde nach einer Benutzertabelle suchen.
thenengah

4
ActiveRecord::Base.connection.table_exists? 'kittenswürde nach einem Kätzchentisch suchen. Es sei denn, ich habe alle Kätzchen vernichtet! drop_table :kittens
Thenengah

1
Danke Leute! Ich habe gerade.index_exists?('kittens', 'paws')
Trip

14
Dies funktioniert für ActiveRecord 3.2.11 drop_table(:hosts_users) if table_exists? :hosts_users
Greg

1
ActiveRecord::Base.connection.data_source_exists? 'table_name'ist jetzt die richtige
Dorian

57

auch wenn keine Tabelle vorhanden ist:

Modell Kitten, erwartete Tischschienen kittens 3:

Kitten.table_exists? # => false


+ 1 Elegantere Lösung. Funktioniert auch, wenn das Modell den Tabellennamen überschreibt.
Daniel Rikowski

1
Bestätigen, dass dies für Rails 2.3.18-lts funktioniert (getestet mit einer vorhandenen Tabelle, eine fehlt, bevor das Skript / die Konsole ausgeführt wird)
iheggie

32

Ich habe dies herausgefunden, als ich versucht habe, eine Tabelle über eine Migration zu entfernen:

drop_table :kittens if (table_exists? :kittens)
ActiveRecord::Migration.drop_table :kittens if (ActiveRecord::Base.connection.table_exists? :kittens)

funktioniert für Rails 3.2

Dieses einfachere Formular wird in Rails 5 verfügbar sein:

drop_table :kittens, if_exists: true

Referenz: https://github.com/rails/rails/pull/16366

Und hier ist der CHANGELOG von Rails 5 ActiveRecord :

Führen Sie die Option: if_exists für drop_table ein.

Beispiel:

drop_table(:posts, if_exists: true)

Das würde ausführen:

DROP TABLE IF EXISTS posts

Wenn die Tabelle nicht vorhanden ist, löst if_exists: false (Standardeinstellung) eine Ausnahme aus, während if_exists: true nichts bewirkt.


Dies schlägt fehl, wenn es sich bei der Tabelle tatsächlich um eine Ansicht handelt, da die Tabelle anscheinend vorhanden ist, DROP TABLE sie jedoch nicht löschen kann.
mcr

8

Schienen 5.1

if ActiveRecord::Base.connection.data_source_exists? 'table_name'
   drop_table :table_name
end

oder

drop_table :table_name, if_exists: true

2
table_exists funktioniert weiterhin in Rails-5, sein Verhalten ändert sich jedoch so, dass nur Tabellen überprüft werden. Ab 5.0.1 werden Ansichten und Tabellen überprüft. data_source_exists behält dieses Verhalten bei und table_exists ändert sich, um nur Tabellen zu überprüfen.
John Naegle

Er bittet nicht darum, die Tabelle auf eine Migration zu überprüfen, er muss sicher sein, dass die Tabelle auf einer
Rechenaufgabe

0

Der richtige Weg, dies zu tun, ist Model.table_exists?

class Dog < ApplicationRecord
  # something
end

do_something if Dog.table_exists?
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.