7

Tôi đang làm việc trên ứng dụng Ruby on Rails. Chúng tôi đang sử dụng cơ sở dữ liệu PostgreSQL.Tạo một chuỗi PostgreSQL cho một trường (không phải là ID của bản ghi)

Có một bảng tên scores với các cột sau:

Column  | Type 
--------------+----------------------- 
id   | integer 
value   | double precision 
ran_at  | timestamp 
active  | boolean 
build_id  | bigint 
metric_id  | integer 
platform_id | integer 
mode_id  | integer 
machine_id | integer 
higher_better | boolean 
job_id  | integer 
variation_id | integer 
step   | character varying(255) 

tôi cần phải thêm một chuỗi-job_id (lưu ý: không có mô hình cho job).

Làm cách nào để tạo chuỗi này?

Trả lời

18

Sử dụng CREATE SEQUENCE:

CREATE SEQUENCE scores_job_id_seq; -- = default name for plain a serial 

Sau đó, thêm một cột mặc định scores.job_id:

ALTER TABLE scores ALTER COLUMN job_id SET DEFAULT nextval('scores_job_id_seq'); 

Nếu bạn muốn bind chuỗi đến cột (vì vậy nó được xóa khi cột là đã xóa), cũng chạy:

ALTER SEQUENCE scores_job_id_seq OWNED BY scores.job_id; 

Tất cả điều này có thể được thay thế bằng cách sử dụng các kiểu dữ liệu giả serial cho cột job_id để bắt đầu với:

Nếu bảng của bạn đã có hàng, bạn có thể muốn thiết lập các SEQUENCE để giá trị cao nhất tiếp theo và điền vào giá trị hàng loạt thiếu trong bảng:

SELECT setval('scores_job_id_seq', COALESCE(max(job_id), 0)) FROM scores; 

tùy ý:

UPDATE scores 
SET job_id = nextval('scores_job_id_seq') 
WHERE job_id IS NULL; 

Sự khác biệt duy nhất còn lại, một cột serial cũng được thiết lập để NOT NULL. Bạn có thể hoặc không muốn điều đó, quá:

ALTER TABLE scores ALTER COLUMN job_id SET NOT NULL; 

Nhưng bạn không thể chỉ thay đổi kiểu của một hiện integer:


             
  
    ALTER TABLE scores ALTER job_id TYPE serial; 
  

serial không phải là một kiểu dữ liệu thực tế. Nó chỉ là một tính năng tiện lợi không hợp lý cho CREATE TABLE.

+0

bạn có thể thực hiện việc này bằng cách sử dụng di chuyển ActiveRecord không? – Tanvir

+2

@taa bạn đã thử tìm kiếm chưa? http://stackoverflow.com/q/7606994/1499698 http://stackoverflow.com/q/7820747/1499698 – pozs

+0

vâng, tôi đã tìm ra. cảm ơn! – Tanvir

13

Vì vậy, tôi đã tìm ra cách để thực hiện việc này bằng cách sử dụng di chuyển ActiveRecord trên Ruby on Rails. Về cơ bản tôi đã sử dụng các lệnh của Erwin và trợ giúp từ this page và đặt chúng trong các tệp di chuyển.Đây là những bước sau:

1. Trong terminal, gõ:

rails g migration CreateJobIdSequence 
rails g migration AddJobIdSequenceToScores 

2. Chỉnh sửa các file chuyển đổi như sau:

20140709181616_create_job_id_sequence.rb:

class CreateJobIdSequence < ActiveRecord::Migration 
    def up 
    execute <<-SQL 
     CREATE SEQUENCE job_id_seq; 
    SQL 
    end 

    def down 
    execute <<-SQL 
     DROP SEQUENCE job_id_seq; 
    SQL 
    end 
end 

20140709182313_add_job_id_sequence_to_scores rb:

class AddJobIdSequenceToScores < ActiveRecord::Migration 
    def up 
    execute <<-SQL 
     ALTER SEQUENCE job_id_seq OWNED BY scores.job_id; 
     ALTER TABLE scores ALTER COLUMN job_id SET DEFAULT nextval('job_id_seq'); 
    SQL 
    end 

    def down 
    execute <<-SQL 
     ALTER SEQUENCE job_id_seq OWNED BY NONE; 
     ALTER TABLE scores ALTER COLUMN job_id SET NOT NULL; 
    SQL 
    end 
end 

3. Di chuyển cơ sở dữ liệu. Trong loại thiết bị đầu cuối:

rake db:migrate 
Các vấn đề liên quan