risposta

18

Prova:

change_column :my_table, :id, :primary_key 

o

my_table.change_column :id, :primary_key 

Alcuni Rails adattatori del database non possono lasciare che si chiama change_column sulla chiave primaria. Se questo è il caso, allora si può sempre chiamare execute per eseguire il cambio utilizzando direttamente SQL:

MySQL:

execute('ALTER TABLE "my_table" CHANGE "id" "id" 
    bigint DEFAULT NULL auto_increment PRIMARY KEY') 

PostgreSQL (metodo 1):

max_id = execute(%%Q{SELECT id FROM "my_table" ORDER BY "id" DESC 
    LIMIT 1}).to_a.first 
execute(%%Q{CREATE SEQUENCE "my_table_id_seq" START #{max_id+1}}) 
execute(%%Q{ALTER TABLE "my_table" ALTER COLUMN "id" 
    TYPE bigint}) 
execute(%%Q{ALTER TABLE "my_table" ALTER COLUMN "id" 
    SET DEFAULT nextval('my_table_id_seq'::regclass)}) 
execute(%%Q{ALTER TABLE "my_table" ADD PRIMARY KEY("id")}) 

PostgreSQL (metodo 2) :

max_id = execute(%%Q{SELECT "id" FROM "my_table" ORDER BY "id" DESC 
    LIMIT 1}).to_a.first 
execute(%%Q{ALTER TABLE "my_table" RENAME COLUMN "id" TO "id_orig"}) 
execute(%%Q{ALTER TABLE "my_table" ADD COLUMN "id" bigserial NOT NULL}) 
execute(%%Q{UPDATE "my_table" SET "id"="id_orig"}) 
execute(%%Q{ALTER SEQUENCE "my_table_id_seq" RESTART #{max_id+1}}) 
execute(%%Q{ALTER TABLE "my_table" DROP COLUMN "id_orig"}) 

Se non si desidera utilizzare bigint/bigserial (64-bit), utilizzare invece int(11)/.

+0

Thnx per la risposta, ma in realtà ho già fatto change_column su alcune delle chiavi primarie. Potrebbe essere il motivo per cui ha rimosso l'opzione Auto Increment già esistente dall'opzione chiave primaria. –

+0

Nessun problema. Vedi il mio aggiornamento. – vladr

1

Il codice Postgres non funziona, è impossibile utilizzare seriale o bigserial in un'istruzione ALTER TABLE. SQL corretto per PostgreSQL è

ALTER TABLE table ALTER COLUMN id TYPE int 
ALTER TABLE table ALTER COLUMN id TYPE bigint 
3

non ho controllato le altre versioni, ma on Rails 5 si può semplicemente impostare l'opzione auto_increment:

change_column :table_name, :id, :int, null: false, unique: true, auto_increment: true 

O se volete un bigint:

change_column :table_name, :id, :bigint, null: false, unique: true, auto_increment: true 
Problemi correlati