Répondre

18

Essayez:

change_column :my_table, :id, :primary_key 

ou

my_table.change_column :id, :primary_key 

Certains adaptateurs de base de données Rails ne peut pas vous laisser appeler change_column sur la clé primaire. Si tel est le cas, alors vous pouvez toujours appeler execute pour effectuer le changement en utilisant directement SQL:

MySQL:

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

PostgreSQL (méthode 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 (méthode 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"}) 

Si vous ne souhaitez pas utiliser bigint/bigserial (64 bits), utilisez int(11)/integer/serial à la place.

+0

Thnx pour votre réponse, Mais j'ai déjà fait change_column sur certaines des clés primaires. Peut-être que c'est pourquoi il a supprimé l'option Auto Increment déjà existante de l'option clé primaire. –

+0

Pas de problème. Voir ma mise à jour – vladr

1

Votre code Postgres ne fonctionne pas, il est impossible d'utiliser serial ou bigserial dans une instruction ALTER TABLE. SQL correcte pour PostgreSQL est

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

Je n'ai pas vérifié les autres versions, mais on Rails 5, vous pouvez simplement définir l'option auto_increment:

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

Ou si vous voulez un bigint:

change_column :table_name, :id, :bigint, null: false, unique: true, auto_increment: true 
Questions connexes