【问题标题】:When renaming column in Users table getting: SQLite3::ConstraintException: FOREIGN KEY constraint failed: DROP TABLE "users"当重命名用户表中的列时:SQLite3::ConstraintException: FOREIGN KEY constraint failed: DROP TABLE "users"
【发布时间】:2018-08-13 02:14:10
【问题描述】:

我正在使用 Sqlite 开发 Rails 应用程序,并且有一个用户表与其他几个表相关联。尝试重命名用户中的列时,运行 rails db:migrate 时出现主题错误。

我在这里看到很多类似问题的帖子,但没有一个有效。具体来说,常见的补救措施似乎是对所有 has_many 和 has_one 关联使用“dependent::destroy”。我正在这样做,但仍然出现错误。

我做错了什么?

下面是我的代码:

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
  :recoverable, :rememberable, :trackable, :validatable

  has_one :profile, dependent: :destroy
  has_many :bikes, dependent: :destroy
  has_many :bookings, dependent: :destroy
  has_many :rented_bikes, through: :bookings, source: :bike
  has_many :conversations, dependent: :destroy
  has_many :likes, dependent: :destroy
  has_many :liked_bikes, through: :likes, :source => :bike
  has_many :viewed_bikes, through: :views, :source => :bike
  has_many :views, dependent: :destroy
  has_many :reviews, dependent: :destroy
end

class Profile < ApplicationRecord
  belongs_to :user
end

class Bike < ApplicationRecord
  belongs_to :user
  has_many :images, dependent: :destroy
  has_many :bookings, dependent: :destroy
  has_many :booked_users, through: :bookings, source: :user
  has_many :conversations, dependent: :destroy
  has_many :likes, dependent: :destroy
  has_many :liking_users, :through => :likes, :source => :user
  has_one :amenity, dependent: :destroy
  has_many :places, dependent: :destroy
  has_many :views, dependent: :destroy
end

class Booking < ApplicationRecord
  belongs_to :bike
  belongs_to :user

  has_one :review, dependent: :destroy

  validates :date_start, presence: true
  validates :date_end, presence: true
  validates :user_id, presence: true
end

class Conversation < ApplicationRecord
  belongs_to :user
  belongs_to :bike

  has_many :messages, dependent: :destroy
end

class Like < ApplicationRecord
  belongs_to :user
  belongs_to :flat
end

class View < ApplicationRecord
  belongs_to :user
  belongs_to :flat
end

class Review < ApplicationRecord
  belongs_to :user
  belongs_to :booking
end

迁移:

class ChangeCustomerIdToUserId < ActiveRecord::Migration[5.1]
  def change
    rename_column :users, :customer_id, :client_id
  end
end

【问题讨论】:

    标签: ruby-on-rails sqlite foreign-keys


    【解决方案1】:

    你有几个问题同时发生:

    1. SQLite 不支持重命名列,因此 ActiveRecord 驱动程序以硬方式实现列重命名:使用新列名创建一个新表,复制所有数据,删除原始表,重命名新表。 请注意,这里有 recently changed,因此最新的 SQLite 确实支持就地重命名列。
    2. 您在引用您的users 表的其他表中有外键。

    (2) 是在迁移期间触发错误的原因:当有外键引用表时,您不能删除表(请参阅 (1))因为删除表会违反这些外键。

    解决方案是删除迁移中所有有问题的 FK,然后执行 rename_column,然后重新添加所有 FK。另一种选择是尝试关闭 FK 并在迁移中重新打开它们,例如:

    connection.execute("PRAGMA defer_foreign_keys = ON")
    connection.execute("PRAGMA foreign_keys = OFF")
    rename_column :users, :customer_id, :client_id
    connection.execute("PRAGMA foreign_keys = ON")
    connection.execute("PRAGMA defer_foreign_keys = OFF")
    

    可能会起作用。


    三个月前有一个commit made to Rails 应该可以解决这个问题,但我认为它还没有进入任何发布版本。

    【讨论】:

    • 很有趣,谢谢。我肯定会在我的下一个项目中使用 PostgreSQL...
    猜你喜欢
    • 2019-12-04
    • 1970-01-01
    • 2018-06-10
    • 2020-08-07
    • 2019-11-14
    • 2019-05-12
    • 1970-01-01
    • 2020-08-11
    • 2022-08-22
    相关资源
    最近更新 更多