带有 UUID 主键的 ActiveRecord 迁移

发布于 2024-10-17 03:51:33 字数 680 浏览 8 评论 0原文

在我要创建的迁移中,表的主键是一个名为“id”的字段,但它不是一个自动递增的整数。它的数据类型应该是唯一标识符(uuid)。这是我尝试过的:

create_table :some_things, :id => false do |t|
  t.column :id, :uniqueidentifier, :primary => true
  t.column :name, :string, :limit => 255
  t.column :type, :tinyint
  t.column :deleted_flag, :bit
  t.column :class_id, :uniqueidentifier
  t.timestamps
end

这可以正常创建表,但没有主键(因为我说:id=>false)。如果我说“create_table :some_things, :id => true, :primary => :id”,那么“id”成为主键,但它是一个自增整数,而不是非自增uuid 。

如何使此迁移工作,以便主键是“uniqueidentifier”类型(非自动递增)的名为“id”的字段?

我正在使用: SQL Server 2008, Rails/ActiveRecord 3.0.3, activerecord-sqlserver-adapter gem, 和 ODBC 连接。

In the migration that I want to create, the primary key of the table is a field called "id" but it is not an auto-incrementing integer. It's datatype should be uniqueidentifier (a uuid). Here is what I have tried:

create_table :some_things, :id => false do |t|
  t.column :id, :uniqueidentifier, :primary => true
  t.column :name, :string, :limit => 255
  t.column :type, :tinyint
  t.column :deleted_flag, :bit
  t.column :class_id, :uniqueidentifier
  t.timestamps
end

This creates the table alright, but there is no primary key (because I said :id=>false). If I said "create_table :some_things, :id => true, :primary => :id", then "id" becomes the primary key, but it is an auto-incrementing integer, not a non-auto-incrementing uuid.

How can I make this migration work so that the primary key is a field called "id" of type "uniqueidentifier" (non-auto-incrementing)?

I'm using:
SQL Server 2008,
Rails/ActiveRecord 3.0.3,
the activerecord-sqlserver-adapter gem,
and an ODBC connection.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

没企图 2024-10-24 03:51:33

我不知道如何直接解决问题,但我有一个解决方法。

输入不带“primary”指令的迁移列 ID。在迁移中的方法“create_table”之后执行 SQL 的添加约束

execute "ALTER TABLE some_things ADD PRIMARY KEY (id);"

(不要使用 MSSQL,并且 SQL 语法可能会出错)

在模型中通过添加

self.primary_key = "id"

或定义主键

set_primary_key :id

I don't know how to solve problem directly, but I've got a workaround.

Put in your migration column id without 'primary' directive. And after method 'create_table' in migration execute SQL's add constraint

execute "ALTER TABLE some_things ADD PRIMARY KEY (id);"

(don't use MSSQL and may be mistake in SQL-syntax for it)

In your model define primary key by adding

self.primary_key = "id"

or

set_primary_key :id
幸福丶如此 2024-10-24 03:51:33

以下是我解决这个问题的方法:

1) 在迁移中,我允许迁移自动生成 id 和 id_sequence,并添加一个虚拟 uuid 列(此处称为 guid)。这只是开发道路上最简单的方法。所以

class Thing < ActiveRecord::Base
  attr_accessible :name, :description, :guid
end

我使用迁移

class CreateThings < ActiveRecord::Migration
  def change
    create_table :things do |t|
      t.string :name
      t.string :description
      t.uuid :guid

      t.timestamps
    end
  end
end

2) 迁移后,我可以通过 sql 客户端运行以下命令

ALTER TABLE things DROP CONSTRAINT things_pkey;
ALTER TABLE things ADD PRIMARY KEY (guid);
ALTER TABLE things DROP COLUMN id;
ALTER TABLE things RENAME COLUMN guid TO id;

3) 我使用两个 gem 来帮助解决这个问题

gem 'uuidtools'
gem 'postgres_ext'

显然,我的解决方案是针对 Postgres DB ...但我发布这个是因为它似乎与你的问题之一相关,即你如何使用 Rails 来保持数据库的距离?无论如何,UUIDtools 与数据库无关。

4)在我的 Thing 类中,我使用这个

class Thing < ActiveRecord::Base
  include Extensions::UUID

,其中 UUID 只是一个像这样的模块

module Extensions
  module UUID
    extend ActiveSupport::Concern

    included do
      # set_primary_key 'guid'
      before_create :generate_uuid

      def generate_uuid
        self.id = UUIDTools::UUID.random_create.to_s
      end
    end
  end
end

顺便说一句,我在这个要点中找到了后者:

https://gist.github.com/rmoriz/937739

但我的解决方案有点不同。

Here was how I solved this problem:

1) In my migration, I allowed the migration to autogenerate the id and the id_sequence, and added a dummy uuid column (called guid here). It was simply the easiest way to go in the development path. So for

class Thing < ActiveRecord::Base
  attr_accessible :name, :description, :guid
end

I use migration

class CreateThings < ActiveRecord::Migration
  def change
    create_table :things do |t|
      t.string :name
      t.string :description
      t.uuid :guid

      t.timestamps
    end
  end
end

2) After the migration, I can run the following through a sql client

ALTER TABLE things DROP CONSTRAINT things_pkey;
ALTER TABLE things ADD PRIMARY KEY (guid);
ALTER TABLE things DROP COLUMN id;
ALTER TABLE things RENAME COLUMN guid TO id;

3) I am using two gems to help with this

gem 'uuidtools'
gem 'postgres_ext'

Clearly, my solution is against a Postgres DB ... but I post this because it seems relevant to one of your issues, namely how do you use Rails to keep the db at arms length? At any rate UUIDtools is db agnostic.

4) In my Thing class I use this

class Thing < ActiveRecord::Base
  include Extensions::UUID

where UUID is simply a module like so

module Extensions
  module UUID
    extend ActiveSupport::Concern

    included do
      # set_primary_key 'guid'
      before_create :generate_uuid

      def generate_uuid
        self.id = UUIDTools::UUID.random_create.to_s
      end
    end
  end
end

By the way, I found the latter in this gist:

https://gist.github.com/rmoriz/937739

But my solution is a little different.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文