ตรวจสอบว่ามีตารางอยู่ใน Rails หรือไม่


174

ฉันมีงานเรคที่ไม่สามารถทำงานได้หากไม่มีตาราง ฉันทำงานกับวิศวกรมากกว่า 20 คนในเว็บไซต์ดังนั้นฉันต้องการตรวจสอบให้แน่ใจว่าพวกเขาได้ย้ายตารางก่อนที่พวกเขาจะสามารถทำงานคราดซึ่งจะเติมข้อมูลในตารางนั้น

AR มีวิธีการเช่นนี้Table.existsหรือไม่? ฉันจะแน่ใจได้อย่างไรว่าพวกเขาย้ายข้อมูลตารางเรียบร้อยแล้ว


12
เรื่องตลกไป .. วิธีการหลายวิศวกรมันจะใช้เวลาในการโยกย้ายตาราง :)
Zabba

1
เกี่ยวกับการผลิต 1. ในการแสดงละครหลายสิบและหลายครั้งในแต่ละ
thenengah

2
มันจะง่ายกว่าหรือไม่เพียงแค่เรียกใช้การย้ายข้อมูลในตอนเริ่มต้นของงานเรคของคุณ? ดังนั้นคุณไม่ต้องกังวลกับตารางที่หายไป
raskhadafi

@raskhadafi: โปรดทราบว่าตารางที่หายไปจะทำให้คุณมีปัญหาหาก config / initializers ของคุณใช้ (เช่นแม้rake db:migrateจะล้มเหลว)
ocodo

คำตอบ:


302

ในทางรถไฟ 5 API กลายเป็นที่ชัดเจนเกี่ยวกับตาราง / มุมมองรวมแหล่งข้อมูล

# 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'

ในรางที่ 2, 3 และ 4 API เป็นเรื่องเกี่ยวกับตาราง

# 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'

รับสถานะของการย้ายข้อมูล:

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

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

หากคุณต้องการ API เพิ่มเติมสำหรับการย้ายข้อมูลหรือข้อมูลเมตาดู:

  • ActiveRecord :: SchemaMigration
    นี่เป็นActiveRecord::Baseคลาสสำหรับschema_migrationsตาราง
  • ActiveRecord :: Migrator
    ที่การกระทำทั้งหมดเกิดขึ้นเมื่อมีการเรียกใช้การย้ายข้อมูล

4
ActiveRecord::Base.connection.table_exist 'users'จะตรวจสอบตารางผู้ใช้
thenengah

4
ActiveRecord::Base.connection.table_exists? 'kittensจะตรวจสอบตารางลูกแมว นั่นคือถ้าฉันทำลายลูกแมวทั้งหมด! drop_table :kittens
thenengah

1
ขอบคุณเพื่อน! ฉันเพิ่งใช้.index_exists?('kittens', 'paws')
เดินทาง

14
ใช้งานได้กับ ActiveRecord 3.2.11 drop_table(:hosts_users) if table_exists? :hosts_users
Greg

1
ActiveRecord::Base.connection.data_source_exists? 'table_name'ถูกต้อง
Dorian

57

แม้ว่าตารางจะไม่มีอยู่:

รูปแบบ รางรางKittenคาดkittens3:

Kitten.table_exists? # => false


+ 1 ทางออกที่สง่างามมากขึ้น ยังใช้งานได้หากโมเดลแทนที่ชื่อตาราง
Daniel Rikowski

1
ยืนยันงานนี้ราว 2.3.18-LTS (ทดสอบกับหนึ่งในปัจจุบันตารางหนึ่งที่ขาดหายไปก่อนที่จะใช้สคริปต์ / คอนโซล)
iheggie

32

ฉันพบสิ่งนี้ในขณะที่ฉันพยายามลบตารางผ่านการย้ายข้อมูล:

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

ทำงานกับ Rails 3.2

แบบฟอร์มที่ง่ายกว่านี้จะมีให้ใน Rails 5:

drop_table :kittens, if_exists: true

การอ้างอิง: https://github.com/rails/rails/pull/16366

และนี่คือCHANGELOGของ Rails 5 ActiveRecord :

แนะนำตัวเลือก: if_exists สำหรับ drop_table

ตัวอย่าง:

drop_table(:posts, if_exists: true)

ที่จะดำเนินการ:

DROP TABLE IF EXISTS posts

หากไม่มีตาราง if_exists: false (ค่าเริ่มต้น) ทำให้เกิดข้อยกเว้นในขณะที่ if_exists: จริงไม่ทำอะไรเลย


สิ่งนี้จะล้มเหลวหากตารางเป็นมุมมองเนื่องจากตารางดูเหมือนจะมีอยู่ แต่ตาราง DROP ไม่สามารถวางได้
mcr

8

Rails 5.1

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

หรือ

drop_table :table_name, if_exists: true

2
table_exists ยังคงใช้งานได้ในราง -5 แต่พฤติกรรมของมันจะเปลี่ยนเป็นตารางตรวจสอบเท่านั้น จาก 5.0.1 จะตรวจสอบมุมมองและตาราง data_source_exists เก็บพฤติกรรมนั้นและ table_exists จะเปลี่ยนเป็นตรวจสอบตารางเท่านั้น
John Naegle

เขาไม่ได้ขอให้ตรวจสอบตารางเกี่ยวกับการย้ายถิ่นเขาจำเป็นต้องตรวจสอบให้แน่ใจว่าตารางนั้นมีอยู่ในภารกิจที่คราด
Juan Furattini

0

วิธีที่เหมาะสมในการทำเช่นนี้คือ Model.table_exists?

class Dog < ApplicationRecord
  # something
end

do_something if Dog.table_exists?
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.