【问题标题】:Ruby mysql gem - How to avoid datetime automatic cast to string while queryingRuby mysql gem - 如何在查询时避免日期时间自动转换为字符串
【发布时间】:2017-03-06 19:34:20
【问题描述】:

有没有办法将 MySQL 数据库的日期时间列加载到 Mysql gem 的结果中,该结果可枚举为 Ruby 日期时间对象(不是字符串类型对象)?

例如:

在数据库端,我们有这张表,里面有以下插入:

create table ContentDB.test_table
(
    id integer primary key auto_increment,
    last_update_date datetime,
    value varchar(128)
);

insert into ContentDB.test_table(last_update_date, value) values (sysdate(), 'Some test stuff..');
commit;

在 Ruby 方面,我们有以下代码(作为名为 test.rb 的文件):

require 'rubygems'
require 'mysql'
require 'date'

begin
    con = Mysql.new "localhost", "root", "root", "ContentDB" 
    rs = con.query "select * from test_table"
    rs.each_hash do |row|
        l_datetime_field = row['last_update_date'].strftime("%Y%m%d%H%M%S")
    end
    con.close
end

这会出现以下错误:

test.rb:9:in `block in <main>': undefined method `strftime' for "2017-03-06 22:15:17":String (NoMethodError)

我知道我可以将即将到来的“字符串”值显式转换为日期时间对象。

但我相信,不应该是这样。我希望我的行是完全相同的行类型(pl/sql 术语),即每个字段都与数据库列类型对应。也就是说

row['last_update_date']

必须是“日期时间”数据类型。

在不使用 rails 的 ActiveRecord 的情况下,是否有隐含的方式在 Ruby 中实现这一点?

最好的问候,

【问题讨论】:

    标签: mysql ruby datetime casting rubygems


    【解决方案1】:

    如果您想要更多的功能,您需要使用比超级基本 MySQL 驱动程序更高级别的适配器。这意味着使用ActiveRecord,或者如果你想要更轻量级的东西,Sequel

    至少不要使用mysql gem,使用mysql2 gem。

    旧版mysql 驱动程序并不真正理解MySQL binary protocol 中的许多类型,并且默认情况下似乎将它们转换为字符串。这是该软件包的基本限制,在不久的将来不太可能改变。

    【讨论】:

    • 首先感谢您的评论。我刚试过续集。不幸的是完全相同的错误。 ActiveRecord 对于我的目的来说太重了(需要太多的配置作为 database.yml)。无论如何,再次感谢您的回答。
    • Sequel 在转换为正确的类型之前可能需要知道您的架构是什么。它有一种在模型中定义它的方法,让你的生活更轻松。
    • @MehmetKaplan 不确定您的意思需要大量配置这可以是使用ActiveRecord::Base.establish_connection 的单个文件(我们一直使用它)。 mysql2 gem 会尝试为您键入 cast,尽管即使他们声明这是 "primitive" 但可能是您需要的。 mysql gem 现在没有维护,所以我不希望有任何变化,因为 mysql2 现在基本上已经取代了它。
    • @engineersmnky,@tadman 谢谢你们。 ActiveRecord::Base.establish_connectionActiveRecord::Base.connection.select_all 的组合解决了我的问题。我将在下面发布最终代码。
    【解决方案2】:

    感谢@engineersmnky、@tadman 在@tadman 的回答下提供的cmets,我的问题已解决。解决方案测试代码如下:

    require "rubygems"
    require "active_record"
    
    begin
        con = ActiveRecord::Base.establish_connection(adapter: "mysql2", host: "localhost",  username: "root", password: "yeahright;-)", database: "ContentDB")
        l_sql = "select * from ContentDB.test_table"
    
        ActiveRecord::Base.connection.select_all(l_sql).each do |row|
            l_datetime_field = row['last_update_date'].strftime("%Y%m%d%H%M%S")
            puts row
            puts l_datetime_field
        end
    end
    

    【讨论】:

    • database.yml 可能很烦人,但它比在部署时必须更改源代码来更改凭据要烦人得多。尝试在代码中保留密码尤其是在提交版本控制系统时。
    • 感谢@tadman,我完全了解安全问题。 :-) 这些只是要测试的脚本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-23
    • 1970-01-01
    • 2011-06-12
    相关资源
    最近更新 更多