codememo

기존 테이블에 타임스탬프 추가

tipmemo 2023. 6. 2. 20:34
반응형

기존 테이블에 타임스탬프 추가

.created_at&updated_at를 기존 테이블로 이동합니다를 기존 테이블로 이동합니다.다음 코드를 시도해 보았지만 작동하지 않았습니다.

class AddTimestampsToUser < ActiveRecord::Migration
    def change_table
        add_timestamps(:users)
    end
end

에에서만 할 수 .create_table열수동으로 할 수 . 열 유형을 수동으로 지정하여 다음 열을 추가할 수 있습니다.

class AddTimestampsToUser < ActiveRecord::Migration
  def change_table
    add_column :users, :created_at, :datetime, null: false
    add_column :users, :updated_at, :datetime, null: false
  end
end

이 구문은 다음과 동일하지 않습니다.add_timestamps위에서 지정한 방법을 사용하면 레일즈는 이러한 열을 타임스탬프 열로 처리하고 값을 정상적으로 업데이트합니다.

두 방법 3 방법)일입니다.up그리고.down (그리고때는로a).change의입니다.을 내변용다것추입다니가할음에경에 .up방법:

class AddTimestampsToUser < ActiveRecord::Migration
  def self.up # Or `def up` in 3.1
    change_table :users do |t|
      t.timestamps
    end
  end
  def self.down # Or `def down` in 3.1
    remove_column :users, :created_at
    remove_column :users, :updated_at
  end
end

경우에는 3.1을 .change 데이브 (음악):

class AddTimestampsToUser < ActiveRecord::Migration
  def change
    change_table(:users) { |t| t.timestamps }
  end
end

아마도 당신은 혼란스러울 것입니다.def change,def change_table,그리고.change_table.

자세한 내용은 마이그레이션 안내서를 참조하십시오.

@user1899434의 응답은 여기서 "기존" 테이블이 이미 있는 레코드, 삭제하고 싶지 않은 레코드를 포함하는 테이블을 의미할 수 있다는 사실에 주목했습니다.따라서 null: false로 타임스탬프를 추가하면 기존 레코드가 모두 비활성화됩니다.

그러나 저는 두 단계를 하나의 마이그레이션으로 결합하고 보다 의미론적인 add_timestamps 방법을 사용함으로써 답변을 개선할 수 있다고 생각합니다.

def change
  add_timestamps :projects, default: Time.zone.now
  change_column_default :projects, :created_at, nil
  change_column_default :projects, :updated_at, nil
end

다른 타임스탬프로 대체할 수 있습니다.DateTime.now시간이 시작될 때 기존의 레코드를 생성/삭제하는 것과 같은 작업을 수행할 수 있습니다.

원래 코드가 오른쪽에 매우 가깝기 때문에 다른 메서드 이름을 사용하면 됩니다. 3 Rails 3.1을 .change 대신 change_table:

class AddTimestampsToUser < ActiveRecord::Migration
  def change
    add_timestamps(:users)
  end
end

에는 이버을사는경정우합의니다야해용하전전합다를 정의해야 .up그리고.down대신방 change_table:

class AddTimestampsToUser < ActiveRecord::Migration
  def up
    add_timestamps(:users)
  end

  def down
    remove_timestamps(:users)
  end
end
class AddTimestampsToUser < ActiveRecord::Migration
  def change
    change_table :users do |t|
      t.timestamps
    end
  end
end

사용 가능한 변환은 다음과 같습니다.

change_table :table do |t|
  t.column
  t.index
  t.timestamps
  t.change
  t.change_default
  t.rename
  t.references
  t.belongs_to
  t.string
  t.text
  t.integer
  t.float
  t.decimal
  t.datetime
  t.timestamp
  t.time
  t.date
  t.binary
  t.boolean
  t.remove
  t.remove_references
  t.remove_belongs_to
  t.remove_index
  t.remove_timestamps
end

http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html

기존 데이터가 있는 테이블에 타임스탬프 열을 추가한다는 점에서 Nick Davies 답변이 가장 완벽합니다.그것의 유일한 단점은 그것이 상승할 것이라는 것입니다.ActiveRecord::IrreversibleMigration에서.db:rollback.

양방향으로 작동하도록 다음과 같이 수정해야 합니다.

def change
  add_timestamps :campaigns, default: DateTime.now
  change_column_default :campaigns, :created_at, from: DateTime.now, to: nil
  change_column_default :campaigns, :updated_at, from: DateTime.now, to: nil
end

여기서 대부분의 답변의 문제는 기본적으로 다음과 같은 경우입니다.Time.zone.now모든 레코드에는 마이그레이션이 실행된 시간이 기본 시간으로 지정됩니다. 이 시간은 사용자가 원하는 시간이 아닐 수 있습니다. 레에 5서대사수있니다습할용을 할 수 .now()기존 레코드의 타임스탬프는 마이그레이션이 실행된 시간과 새로 삽입된 레코드에 대한 커밋 트랜잭션의 시작 시간으로 설정됩니다.

class AddTimestampsToUsers < ActiveRecord::Migration def change add_timestamps :users, default: -> { 'now()' }, null: false end end

용사를 합니다.Time.current좋은 스타일입니다. https://github.com/rubocop-hq/rails-style-guide#timenow

def change
  change_table :users do |t|
    t.timestamps default: Time.current
    t.change_default :created_at, from: Time.current, to: nil
    t.change_default :updated_at, from: Time.current, to: nil
  end
end

또는

def change
  add_timestamps :users, default: Time.current
  change_column_default :users, :created_at, from: Time.current, to: nil
  change_column_default :users, :updated_at, from: Time.current, to: nil
end
def change
  add_timestamps :table_name
end

저는 5.0 레일을 타고 있는데, 이 옵션들 중 어떤 것도 작동하지 않았습니다.

유일하게 작동한 것은 type to be:timestamp와 not:datetime입니다.

def change
    add_column :users, :created_at, :timestamp
    add_column :users, :updated_at, :timestamp
end

정확히 언제 이 기능이 도입되었는지는 확실하지 않지만 레일 5.2.1에서는 다음을 수행할 수 있습니다.

class AddTimestampsToMyTable < ActiveRecord::Migration[5.2]
  def change
    add_timestamps :my_table
  end
end

자세한 내용은 활성 레코드 마이그레이션 문서의 "변경 방법 사용"을 참조하십시오.

이것은 Rails 5.0.7의 깨끗한 솔루션처럼 보입니다(change_column_null 방법 발견).

def change
  add_timestamps :candidate_offices, default: nil, null: true
  change_column_null(:candidate_offices, :created_at, false, Time.zone.now)
  change_column_null(:candidate_offices, :created_at, false, Time.zone.now)
end

여기에 많은 답변이 있지만, 이전의 것들 중 어느 것도 저에게 효과가 없었기 때문에 제 것도 게시하겠습니다 :)

몇몇 사람들이 지적했듯이,#add_timestamps불행하게도 그것을 덧붙입니다.null: false제한: 이전 행에 이러한 값이 채워지지 않았기 때문에 이 행은 유효하지 않습니다.합니다.Time.zone.now하지만 오래된 데이터에 대한 이러한 기본 타임스탬프는 정확하지 않을 것이기 때문에 그렇게 하고 싶지 않습니다.테이블에 잘못된 데이터를 추가하는 것이 가치가 없다고 생각합니다.

따라서 마이그레이션은 다음과 같습니다.

class AddTimestampsToUser < ActiveRecord::Migration
  def change_table
    add_column :projects, :created_at, :datetime
    add_column :projects, :updated_at, :datetime
  end
end

아니요.null: false다른 제한은 없습니다. 행은 해서 " " " " " 로 합니다.created_at~하듯이NULL,그리고.update_at~하듯이NULL(행에 대해 일부 업데이트가 수행될 때까지).에는 새행다같습다니과음은다▁have▁new가 표시됩니다.created_at그리고.updated_at예상대로 채워졌습니다.

created_atupdated_at 필드를 각 테이블에 추가하기 위해 호출할 수 있는 간단한 함수를 만들었습니다.

  # add created_at and updated_at to each table found.
  def add_datetime
    tables = ActiveRecord::Base.connection.tables
    tables.each do |t|
      ActiveRecord::Base.connection.add_timestamps t  
    end    
  end

add_sys(table_name, 옵션 = {}) public

table_name에 타임스탬프(created_at 및 updated_at) 열을 추가합니다.추가 옵션(예: null: false)은 #add_column으로 전달됩니다.

class AddTimestampsToUsers < ActiveRecord::Migration
  def change
    add_timestamps(:users, null: false)
  end
end

기존 테이블에 타임스탬프를 추가할 수 있는 간단한 테이블입니다.

class AddTimeStampToCustomFieldMeatadata < ActiveRecord::Migration
  def change
    add_timestamps :custom_field_metadata
  end
end

레일 6(및 그 이전)에서 다음과 같은 레코드가 이미 존재하는 기존 테이블에 타임스탬프를 추가하려고 할 경우:

def change
  add_timestamps :table_name
end

라는 사실 때문에 당신은 오류를 얻을 것입니다.add_timestamps기본적으로 새 열은 NOT NULL로 선언됩니다.다음을 추가하여 이 문제를 해결할 수 있습니다.null: true주장으로서:

def change
  add_timestamps :table_name, null: true
end

앞의 답변이 맞는 것 같지만 테이블에 이미 항목이 있는 경우 문제가 발생했습니다.

'ERROR: 열'이 표시됩니다.created_at를 포함합니다.null가치관'.

수정하기 위해 다음을 사용했습니다.

def up
  add_column :projects, :created_at, :datetime, default: nil, null: false
  add_column :projects, :updated_at, :datetime, default: nil, null: false
end

그런 다음 gemmigration_data를 사용하여 마이그레이션에 대한 현재 프로젝트 시간을 추가했습니다.

def data
  Project.update_all created_at: Time.now
end

그러면 이 마이그레이션 후에 생성된 모든 프로젝트가 올바르게 업데이트됩니다..ActiveRecord레코드의 타임스탬프 추적을 시작합니다.

이와 같은 마이그레이션을 사용하여 다음을 추가할 수 있습니다.created_at그리고.updated_at열을 기존 레코드가 있는 기존 테이블로 이동합니다.이 마이그레이션은 다음을 설정합니다.created_at그리고.updated_at현재 날짜 시간까지의 기존 레코드 필드.

이 예를 위해 테이블 이름을 다음과 같이 입력합니다.users은 그고모델은명리입니다.User

class AddTimestampsToTcmOrders < ActiveRecord::Migration[6.0]
  def up
    # Add timestamps to the users table with null as true cause there are existing records
    add_timestamps(:users, null: true)

    # Update existing records with non-nil timestamp values
    User.update_all(created_at: DateTime.now, updated_at: DateTime.now)

    # change columns so they can't be nil
    change_column(:users, :updated_at, :datetime, null: false, precision: 6)
    change_column(:users, :created_at, :datetime, null: false, precision: 6)
  end

  def down
    remove_column :users, :updated_at
    remove_column :users, :created_at
  end
end

레일즈를 사용하지 않지만 활성 레코드를 사용하는 사용자의 경우 다음은 정수 필드의 예와 같이 기존 모델에 열을 추가합니다.

ActiveRecord::Schema.define do
  change_table 'MYTABLE' do |table|
    add_column(:mytable, :my_field_name, :integer)
  end
end

그건…change,것은 아니다.change_table 4 4.2의 경우:

class AddTimestampsToUsers < ActiveRecord::Migration
  def change
    add_timestamps(:users)
  end
end

제가 개인적으로 사용한 내용은 다음과 같습니다. 이전 기록은 모두 현재 날짜로 업데이트되었습니다.

add_column :<table>, :created_at, :datetime, default: Time.zone.now, null: false
add_column :<table>, :updated_at, :datetime, default: Time.zone.now, null: false

레일 5에서 동일한 문제가 발생했습니다.

change_table :my_table do |t|
    t.timestamps
end

다음을 사용하여 타임스탬프 열을 수동으로 추가할 수 있었습니다.

change_table :my_table do |t|
    t.datetime :created_at, null: false, default: DateTime.now
    t.datetime :updated_at, null: false, default: DateTime.now
end

언급URL : https://stackoverflow.com/questions/7542976/add-timestamps-to-an-existing-table

반응형