7

Sto lavorando a un'app Ruby on Rails. Stiamo usando un database PostgreSQL.Creazione di una sequenza PostgreSQL in un campo (che non è l'ID del record)

C'è una tabella denominata scores con le seguenti colonne:

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) 

ho bisogno di aggiungere una sequenza di -job_id (nota: non c'è modello per job).

Come si crea questa sequenza?

risposta

18

Uso CREATE SEQUENCE:

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

quindi aggiungere un valore predefinito di colonna per scores.job_id:

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

Se si vuole legano la sequenza alla colonna (in modo che venga eliminato quando la colonna è cancellato), eseguire anche:

ALTER SEQUENCE scores_job_id_seq OWNED BY scores.job_id; 

Tutto questo può essere sostituito con l'utilizzo del tipo pseudo dati serial per la colonna job_id per cominciare:

Se la tabella ha già righe, è possibile impostare il SEQUENCE a il successivo valore più alto e riempire valori seriali mancanti nella tabella:

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

Facoltativamente:

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

La differenza unica rimasta, una colonna serial è anche impostato NOT NULL. Si può o non può decidere anche questo:

ALTER TABLE scores ALTER COLUMN job_id SET NOT NULL; 

Ma si può non solo modificare il tipo di un integer esistente:


             
  
    ALTER TABLE scores ALTER job_id TYPE serial; 
  

serial non è un tipo di dati effettivo. È solo una caratteristica di convenienza notazionale per CREATE TABLE.

+0

è possibile farlo utilizzando la migrazione di ActiveRecord? – Tanvir

+2

@taa hai provato a cercarlo? http://stackoverflow.com/q/7606994/1499698 http://stackoverflow.com/q/7820747/1499698 – pozs

+0

sì, l'ho già capito. Grazie! – Tanvir

13

Quindi ho capito come eseguire questa operazione utilizzando le migrazioni di ActiveRecord su Ruby on Rails. Fondamentalmente ho usato i comandi e l'aiuto di Erwin da this page e li ho inseriti nei file di migrazione.Questi sono i passi:

1. Nel terminale, tipo:

rails g migration CreateJobIdSequence 
rails g migration AddJobIdSequenceToScores 

2. Modifica i file della migrazione come segue:

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. migrare il database. Nel tipo di terminale:

rake db:migrate 
Problemi correlati