如何将数据库中的数据从字符串更改为id-Rails,Mysql

如何将数据库中的数据从字符串更改为id-Rails,Mysql,mysql,ruby-on-rails,database,yaml,rails-migrations,Mysql,Ruby On Rails,Database,Yaml,Rails Migrations,你好,我有可能很容易的问题,也许不是 历史记录:我想用数据库(mysql)的状态替换yaml文件,我在用户表列中有:状态。当我将逻辑替换为db时,我已经创建了模型状态、创建了表并配置了与用户的关系 描述问题:当我在用户表中创建status\u id时,我有两列:“status”和“status\u id”。列“status”是字符串,有很多字符串值,例如“confirm”。如何(使用带状态的种子迁移)并填写“状态id”列。我的意思是,如果“状态”列的值为“已确认”,我希望在“状态\u id”列的

你好,我有可能很容易的问题,也许不是

历史记录:我想用数据库(mysql)的状态替换yaml文件,我在用户表列中有:状态。当我将逻辑替换为db时,我已经创建了模型状态、创建了表并配置了与用户的关系

描述问题:当我在用户表中创建status\u id时,我有两列:“status”和“status\u id”。列“status”是字符串,有很多字符串值,例如“confirm”。如何(使用带状态的种子迁移)并填写“状态id”列。我的意思是,如果“状态”列的值为“已确认”,我希望在“状态\u id”列的值为:1

statuses table:
id name
1   confirmed
2   not confirmed
3   something else


Users table
id status           status_id
1  confirmed        empty
2  confirmed        empty
3  confirmed        empty
4  not confirmed    empty
5  not confirmed    empty
6  something else   empty
7  something else   empty
用户所属对象:状态

状态有很多:用户


问题:我为什么不在网站的“状态”栏中更改名称和类型 数据类型为“id”的“status_id”

回答:因为我需要使用capistrano将其部署到生产环境中 服务器和我不能丢失数据并从状态列中删除数据

鉴于以下(您的)样本数据:

create table statuses (id int, name char(20));
insert into statuses (id, name) values
    (1, 'confirmed'),
    (2, 'not confirmed'),
    (3, 'something else');

create table users (id int, status char(20), status_id int);
insert into users (id, status) values
    (1,'confirmed'),
    (2,'confirmed'),
    (3,'confirmed'),
    (4,'not confirmed'),
    (5,'not confirmed'),
    (6,'something else'),
    (7,'something else');

select * from users;
+------+----------------+-----------+
| id   | status         | status_id |
+------+----------------+-----------+
|    1 | confirmed      |      NULL |
|    2 | confirmed      |      NULL |
|    3 | confirmed      |      NULL |
|    4 | not confirmed  |      NULL |
|    5 | not confirmed  |      NULL |
|    6 | something else |      NULL |
|    7 | something else |      NULL |
+------+----------------+-----------+
7 rows in set (0.00 sec)
update
语句使用
status
中的适当值更新
用户
中的
status\u id
列:

update users u 
   set u.status_id=(select s.id from statuses s where u.status=s.name);
Query OK, 7 rows affected (0.01 sec)
Rows matched: 7  Changed: 7  Warnings: 0

select * from users;
+------+----------------+-----------+
| id   | status         | status_id |
+------+----------------+-----------+
|    1 | confirmed      |         1 |
|    2 | confirmed      |         1 |
|    3 | confirmed      |         1 |
|    4 | not confirmed  |         2 |
|    5 | not confirmed  |         2 |
|    6 | something else |         3 |
|    7 | something else |         3 |
+------+----------------+-----------+
7 rows in set (0.00 sec)

希望这就是您所要求的,因为我的回答既不涉及ruby、yaml,也不涉及rails。

这听起来像是一次性的数据迁移,可以用几种不同的方式处理。一种方法是编写一个一次性脚本或rake任务来更新所有用户

一些任务

desc 'Add status id to existing users'

namespace :users do
  task assign_status: :environment do
    statuses = {}
    Status.all.each {|status| statuses[status.name] = status.id}
    User.all.each do |user|
      user.update_attribute(status_id: statuses[user.status])
    end
  end
end
如果您有很多用户,您可能希望使用性能更高的,因为它使用批处理。您可能还希望在rake任务中添加某种进度报告


这种方法允许您根据现有数据库的副本测试任务。

OK…这是正确的,但是…我需要用ruby on rails编写这个答案…比如使用update\u属性或类似的东西。但是对于答案+1:)哦,谢谢你的+1,但是我担心你必须等待其他答案,因为我不知道如何使用rails来完成。你几乎做到了……但是我没有创建rake任务,而是找到了更好的方法。添加种子迁移并使用sql(类似于“执行”)获取所有状态(字符串)并将其与状态表进行比较(类似于“已确认”=“已确认”),然后使用关系将status.name更改为status.id并将其推送到db。我仍然不知道如何做到这一点…但我知道它最简单的方法和打开/关闭原则将得到维护。您要求使用rails实现这一点。我不确定使用种子文件是否是最好的方式,我不知道您是否希望按照您描述的方式更改列。完成数据更改后,可以运行迁移或任务从用户中删除status.name。但是,您需要确保您采取的任何方法都允许将来将您的应用部署到不同的环境中,例如,让您无缝地运行迁移。