Skip to content

Change Default Primary Keys to BIGINT#26266

Merged
sgrif merged 2 commits intorails:masterfrom
jmccartie:jm/bigint
Dec 5, 2016
Merged

Change Default Primary Keys to BIGINT#26266
sgrif merged 2 commits intorails:masterfrom
jmccartie:jm/bigint

Conversation

@jmccartie
Copy link
Copy Markdown
Contributor

@jmccartie jmccartie commented Aug 24, 2016

Friends don't let friends use INT as a primary key.

— Schneems (@schneems) May 13, 2016

Summary

Per a conversation with @sgrif: changes default primary keys from Integer to BIGINT for both Postgresql and MySQL. Leaves behavior alone for SQLite since this database does not provide support for BIGINT primary keys.

Other Information

For obvious reasons, this also requires foreign keys to change from integer to bigints. As a result the test suite's schema.rb has been change in the necessary places.

I'll squash and add a CHANGELOG entry once the rest looks ok...

@rails-bot
Copy link
Copy Markdown

Thanks for the pull request, and welcome! The Rails team is excited to review your changes, and you should hear from @kaspth (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

This repository is being automatically checked for code quality issues using Code Climate. You can see results for this analysis in the PR status below. Newly introduced issues should be fixed before a Pull Request is considered ready to review.

Please see the contribution instructions for more information.

@sgrif sgrif assigned sgrif and unassigned kaspth Aug 24, 2016
@sgrif
Copy link
Copy Markdown
Contributor

sgrif commented Aug 24, 2016

We'll need to make sure that migrations written against 5.0 and later don't have the type of their primary key changed.

@jmccartie
Copy link
Copy Markdown
Contributor Author

@sgrif Can you recommend a best-practice for ensuring that? Have we done something like that in the past that I can learn from?

@sgrif
Copy link
Copy Markdown
Contributor

sgrif commented Aug 24, 2016

@jmccartie
Copy link
Copy Markdown
Contributor Author

@sgrif Thanks.

@jmccartie
Copy link
Copy Markdown
Contributor Author

@sgrif So override the necessary methods inside class V5_0 ?

@rafaelfranca
Copy link
Copy Markdown
Member

rafaelfranca commented Aug 24, 2016

This is a dup of #24962. While this implementation may be more complete it is really a bad OSS etiquette to finish other people PR without given them a chance to finish it or proper credits.

My recommendation:

  1. pull Make pg adapter use bigserial for pk by default #24962 commits in this PR.
  2. Work on top of that commits

@jmccartie
Copy link
Copy Markdown
Contributor Author

@rafaelfranca Ah - thanks for showing me that. I searched for open PR's, but that didn't turn up for me.

I work at Heroku with @rwz, so I'll cycle around with him and see if we can tag team this.

@rafaelfranca
Copy link
Copy Markdown
Member

👍

@jmccartie
Copy link
Copy Markdown
Contributor Author

I've now entered into the 3rd layer of git rebase hell...

@rafaelfranca
Copy link
Copy Markdown
Member

I've now entered into the 3rd layer of git rebase hell...

lol. This is really tough.

@kaspth
Copy link
Copy Markdown
Contributor

kaspth commented Aug 24, 2016

r? @sgrif

@schneems
Copy link
Copy Markdown
Member

Looks like tests are passing now

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to handle MySQL as well. Is it possible for us to implement this in an adapter agnostic way?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I can make that change.

On Thu, Aug 25, 2016 at 10:13 AM, Sean Griffin notifications@github.com
wrote:

In activerecord/lib/active_record/migration/compatibility.rb
#26266 (comment):

@@ -103,6 +103,16 @@ def index_name_for_remove(table_name, options = {})
end

   class V5_0 < V5_1
  •    def create_table(table_name, options = {})
    
  •      # Since version 5.1 Postgres adapter uses bigserial type for primary
    
  •      # keys by default. This compat layer makes old migrations utilize
    
  •      # serial type instead, the way it used to work before 5.1
    
  •      if connection.adapter_name == "PostgreSQL"
    

This needs to handle MySQL as well. Is it possible for us to implement
this in an adapter agnostic way?


You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
https://github.com/rails/rails/pull/26266/files/de485a4379a265218f1bbea900c08f45e39a93fd#r76285358,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAIJEYj45MhqMMLNBPIkwwMhoRSdHCBuks5qjc1DgaJpZM4JrgwZ
.

@jmccartie
Copy link
Copy Markdown
Contributor Author

@sgrif Added a test for MySQL compatibility. The logic still queues off the adapter name, though. We could move that logic into a default on each adapter, but then we have some sort of "legacy_primary_key" method on the adapter itself, which I liked much less than the ternary.

Thoughts?

@sgrif
Copy link
Copy Markdown
Contributor

sgrif commented Aug 26, 2016

Can we just make the PG adapter do the right thing when the PK type is integer?

@jmccartie
Copy link
Copy Markdown
Contributor Author

jmccartie commented Aug 26, 2016

@sgrif I'm not sure. Both adapters need the logic since we need to ensure MySQL uses integer (and not bigint) and Postgresql uses serial (and not bigserial)

@sgrif
Copy link
Copy Markdown
Contributor

sgrif commented Aug 26, 2016

How about just :integer?

On Thu, Aug 25, 2016 at 11:04 PM Jon McCartie notifications@github.com
wrote:

@sgrif https://github.com/sgrif Something like this?

options[:id] ||= connection.class::LEGACY_PK_TYPE


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#26266 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/ABdWK2-R2Rj-aRqV77WLaJaf0AC5MeBYks5qjlfYgaJpZM4JrgwZ
.

@giedriusr
Copy link
Copy Markdown

We got an error on our CI Build.

ActiveRecord::MismatchedForeignKey: Column `city_id` on table `addresses` has a type of `int(11)`.
This does not match column `id` on `cities`, which has type `bigint(20)`.
To resolve this issue, change the type of the `city_id` column on `addresses` to be :integer. (For example `t.integer city_id`).

What I did was to drop test database and rerun migrations again. Schema was updated afterwards and our build succeeded.

Hope that will help someone.

@thao33
Copy link
Copy Markdown

thao33 commented Jan 30, 2019

How about notation at model? Still integer right?

@synth
Copy link
Copy Markdown

synth commented Feb 24, 2021

Is there official documentation on this?

This is causing a headache for our Rails upgrade because all our primary key types and foreign keys are int, but schema.rb doesn't specify the primary key type, so after upgrade, any database that's created from schema.rb (eg tests and local dev) will have primary keys with bigint but foreign keys that are int and thus will error out due to the mismatch.

Updating the keys is not straightforward because there is a chicken/egg situation. If you add a change_column migration to update the primary keys, you'll still get an error in your migrations when the foreign key migration executes (which is before the latest migration to update the type). And obviously editing earlier migrations has its own problems.

A solution here would be to NOT have implicit primary key types which change with Rails versions, but it's not clear how to manage that in this context of upgrading Rails.

UPDATE: If you're upgrading from Rails 5.0.x or earlier, delete and regenerate your schema.rb files. It looks like implicit primary key types was fixed :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.