简体   繁体   English

如何使用Rails ActiveRecord迁移将主键插入MySQL数据库?

[英]How do I use a Rails ActiveRecord migration to insert a primary key into a MySQL database?

I need to create an AR migration for a table of image files. 我需要为图像文件表创建AR迁移。 The images are being checked into the source tree, and should act like attachment_fu files. 这些图像将被检入源代码树,其行为应类似于attachment_fu文件。 That being the case, I'm creating a hierarchy for them under /public/system. 既然如此,我正在/ public / system下为他们创建一个层次结构。

Because of the way attachment_fu generates links, I need to use the directory naming convention to insert primary key values. 由于attachment_fu生成链接的方式,我需要使用目录命名约定来插入主键值。 How do I override the auto-increment in MySQL as well as any Rails magic so that I can do something like this: 如何覆盖MySQL中的自动增量以及任何Rails魔术,以便可以执行以下操作:

image = Image.create(:id => 42, :filename => "foo.jpg")
image.id #=> 42

Yikes, not a pleasant problem to have. kes,不是一个令人愉快的问题。 The least-kludgy way I can think of to do it is to have some code in your migration that actually "uploads" all the files through attachment-fu, and therefore lets the plugin create the IDs and place the files. 我想到的最不费力的方法是在迁移中包含一些代码,这些代码实际上通过附件-fu“上载”所有文件,因此让插件创建ID并放置文件。

Something like this: 像这样:

Dir.glob("/images/to/import/*.{jpg,png,gif}").each do |path|

  # simulate uploading the image
  tempfile = Tempfile.new(path)
  tempfile.set_encoding(Encoding::BINARY) if tempfile.respond_to?(:set_encoding)
  tempfile.binmode
  FileUtils.copy_file(path, tempfile.path)

  # create as you do in the controller - may need other metadata here
  image = Image.create({:uploaded_data => tempfile})
  unless image.save
    logger.info "Failed to save image #{path} in migration: #{image.errors.full_messages}"
  end

  tempfile.close!
end

A look at attachment-fu's tests might be useful. 看看attachment-fu的测试可能会有用。

image = Image.create(:filename => "foo.jpg") { |r| r.id = 42 }

Unlike, say Sybase, in MySQL if you specify the id column in the insert statement's column list, you can insert any valid, non-duplicate value in the id. 与Sybase说的不同,在MySQL中,如果您在插入语句的列列表中指定了id列,则可以在id中插入任何有效的,非重复的值。 No need to do something special. 不需要做一些特别的事情。

I suspect the rails magic is just to not let rails know the id is auto-increment. 我怀疑Rails的魔力只是不让Rails知道ID是自动递增的。 If this is the only way you'll be inserting into this table, then don't make the id auto_increment. 如果这是插入表的唯一方法, 请不要使id为auto_increment。 Just make in an int not null primary key. 只需输入一个int不为null的主键即可。

Though frankly, this is using a key as data, and so it makes me uneasy. 坦率地说,这是使用密钥作为数据,因此让我感到不安。 If attachment_fu is just looking for a column named "id", make a column named id that's really data, and make a column named "actual_id" the actual, synthetic, auto_incremented key. 如果attachment_fu只是寻找一个名为“ID” ,使列名为id这真是数据,并进行了名为“ACTUAL_ID”的实际,合成,auto_incremented键列。

Here's my kluge: 这是我的克鲁格:

class AddImages < ActiveRecord::Migration
  def self.up
    Image.destroy_all

    execute("ALTER TABLE images AUTO_INCREMENT = 1")

    image = Image.create(:filename => "foo.jpg")
    image.id #=> 1
  end

  def self.down
  end
end

I'm not entirely sure I understand why you need to do this, but if you only need to do this a single time, for a migration, just use execute in the migration to set the ID (assuming it's not already taken, which I can't imagine it would be): 我不确定我是否理解为什么需要执行此操作,但是对于一次迁移,如果只需要一次执行此操作,则只需在迁移中使用execute来设置ID(假设它尚未被使用),无法想象会是):

execute "INSERT INTO images (id, filename) VALUES (42, 'foo.jpg')" 执行“将图像插入ID(文件名,文件名)(42,'foo.jpg')”

I agree with AdminMyServer although I believe you can still perform this task on the object directly: 我同意AdminMyServer,尽管我相信您仍然可以直接在对象上执行此任务:

image = Image.new :filename => "foo.jpg"
image.id = 42
image.save

You'll also need to ensure your id auto-increment is updated at the end of the process to avoid clashes in the future. 您还需要确保在过程结束时更新ID自动递增功能,以免将来发生冲突。

newValue = Images.find(:first, :order => 'id DESC').id + 1
execute("ALTER TABLE images AUTO_INCREMENT = #{newValue}")

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在mysql规范化数据库中使用PRIMARY KEY - How to use PRIMARY KEY in mysql normalized database 如何将主键的值插入到插入查询中 - How do i insert the value of the primary key into a insert query 如何使用Guid主键自动增量在Mysql中批量插入? - How to do bulk insert in Mysql with Guid primary key autoincrement? 如何在插入时使用主键 - How to use the primary key at insert 如何将主键作为外键插入另一个表? - How do I insert the primary key to another table as foreign key? 在测试控制器发布方法时,我如何模拟 MySql 数据库返回的主键 - When testing controllers post method how do I mock primary key returned by MySql database rails / mysql - 如何使ActiveRecord :: StatementInvalid错误无声? - rails/mysql - how do i silence out ActiveRecord::StatementInvalid error? 如何配置 MYSQL DB 以接受 NULL 作为 INSERT 语句中的主键,然后生成唯一的主键 - How can I configure MYSQL DB to accept NULL for primary key in the INSERT statement and then generate unique primary key 如何在插入失败时获取冲突行的主键? - How do I get primary key of colliding row on failed insert? 如何使用 SQL sum function 在具有相应主键的不同 MySQL 表中添加值? - How do I use the SQL sum function to add values in different MySQL tables with the corresponding Primary Key?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM