2

我正在从外部数据库中获取数据,并将其提供给我的 dashing 小部件。

当数值数据返回到小部件时,它看起来像:

mysql::result:0x21A25

我需要这个数据是十进制数。这是获取数据并将其提供给小部件的代码:

require 'mysql2'

SCHEDULER.every '1m', :first_in => 0 do |job|

  # Mysql connection

  db = Mysql2::Client.new(:host => "some ip", :username => "user", :password => "password", :port => 3306, :database => "database_name" )

  # Mysql query

  sql = "SELECT COUNT(*) FROM out_sms WHERE type = 'STANDARD_SMS' "
  # Execute the query
  results = db.query(sql)


  # Update the Man Hours Saved E widget

  send_event('manHoursE', { current: results } )

end
4

3 回答 3

2

Mysql2::Client#query方法将返回一个Mysql2::Result对象,它是一个 Ruby Enumerable。这意味着您可以通过许多不同的方式对其进行迭代,就像使用数组或哈希(results.each {}例如)一样,或者使用Enumerable类似.firstor之类的方法.last

您的查询,没有GROUP BY只能返回一行。所以打电话.first会给你那一行。

# Use an alias for the count, total here
sql = "SELECT COUNT(*) AS total FROM out_sms WHERE type = 'STANDARD_SMS' "
# Execute the query
results = db.query(sql)

# Then retrieve the row using a method like .first
your_row = results.first

# Look at the hash it contains:
puts your_row

# The value you want should be a hash key
puts your_row['total']

然后,您可以your_row['total']在更新方法中使用。

当然,您可以简化这一切,只需使用results.first['total']. 不要忘记将其包装在适当的范围begin ... rescue ... end内以处理错误。

于 2013-10-06T15:47:49.673 回答
0

我强烈建议您研究 Ruby 的 ORM 之一,例如SequelDataMapperActive Record

它们将使您的生活变得更简单,通过使用自己的 DSL 抽象查询,让您专注于逻辑,并且它们会将字段的内容作为 Ruby 中的本机对象返回。没有更多像你看到的问题。

这些工具生成的 SQL 等同于您手动生成的 SQL;你必须努力让他们做错事,而且你很少能改进他们产生的东西。

此外,只需更改您的连接 DSN,您就可以切换到完全不同的数据库管理器,他们会感觉到架构差异,并为新环境生成优化的 SQL。尝试直接与 MySQL、PostgreSQL、Oracle 或 SQLite 驱动程序对话。

这是使用 Sequel 和 SQLite 的代码示例:

require 'sequel'

DB = Sequel.sqlite # memory database

DB.create_table :items do
  primary_key :id
  String :name
  Integer :number
  Float :price
end

items = DB[:items] # Create a dataset

# Populate the table
items.insert(:name => 'abc', :number => 1, :price => rand * 100)
items.insert(:name => 'def', :number => 3, :price => rand * 100)
items.insert(:name => 'ghi', :number => 7, :price => rand * 100)

# Print out the number of records
puts "Item count: #{ items.count }"

# Print out the values:
items.each do |i|
  puts i
end

运行后返回:

Item count: 3
{:id=>1, :name=>"abc", :number=>1, :price=>48.3673258126733}
{:id=>2, :name=>"def", :number=>3, :price=>41.87676958348104}
{:id=>3, :name=>"ghi", :number=>7, :price=>62.54605297923891}

在循环中提取行:

items.each do |i|
  puts i
end

每次循环i都是一个散列,可以很容易地提取单个字段。再次运行代码:

>> item = items.first
{
        :id => 1,
      :name => "abc",
    :number => 1,
     :price => 70.81654554223003
}
>> item.class
Hash < Object

请注意,整数和浮点值是我们所期望的。(“价格”字段的值会有所不同,因为它们是随机的。)

对于 Rails,您会遇到 Active Record,因为它是 ORM。在 Rails 之外使用 Active Record 是可行的,但它是面向该框架的。我们在我的团队中广泛使用 Sequel 进行数据库交互。我的代码合作伙伴最近在大约一个小时内完成了从基于 MySQL 的数据库到 PostgreSQL 的完全转换,方法是更改​​连接字符串、运行我们设置的迁移并启动数据重新加载。他对它的简单性感到非常满意,尤其是因为他不必编写任何 SQL。

Sequel 带有一个基于 IRB 的命令行版本。您可以交互式地查询数据库、修改它们、查看和查看它们的内容。这也是查看将生成什么的好方法:

Your database is stored in DB...
Welcome to SEQUEL. You are using ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.4.0]. Have fun ;)
>> require 'logger'
true
>> DB.loggers << Logger.new(STDOUT)
[
    [0] #<Logger:0x007f7fe41dd880 @progname=nil, @level=0, @default_formatter=#<Logger::Formatter:0x007f7fe41dd858 @datetime_format=nil>, @formatter=nil, @logdev=#<Logger::LogDevice:0x007f7fe41dd808 @shift_size=nil, @shift_age=nil, @filename=nil, @dev=#<IO:<STDOUT>>, @mutex=#<Logger::LogDevice::LogDeviceMutex:0x007f7fe41dd7e0 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0x007f7fe41dd790>>>>
]
>> DB.create_table :items do
 >       primary_key :id
|      String :name
|      Integer :number
|      Float :price
|    end
I, [2013-10-06T09:51:55.752052 #6721]  INFO -- : CREATE TABLE items (id integer PRIMARY KEY AUTOINCREMENT, name varchar(255), number integer, price double precision)
nil
>> items = DB[:items]
#<Sequel::Mock::Dataset: "SELECT * FROM items">
>> items.insert(:name => 'abc', :number => 1, :price => rand * 100)
I, [2013-10-06T09:52:15.421974 #6721]  INFO -- : INSERT INTO items (name, number, price) VALUES ('abc', 1, 22.32640955200822)
nil
>> items.insert(:name => 'def', :number => 3, :price => rand * 100)
I, [2013-10-06T09:52:15.432649 #6721]  INFO -- : INSERT INTO items (name, number, price) VALUES ('def', 3, 43.182983199793824)
nil
>> items.insert(:name => 'ghi', :number => 7, :price => rand * 100)
I, [2013-10-06T09:52:15.441312 #6721]  INFO -- : INSERT INTO items (name, number, price) VALUES ('ghi', 7, 67.81054007143193)
nil
>> items.count
I, [2013-10-06T09:52:23.683121 #6721]  INFO -- : SELECT count(*) AS count FROM items LIMIT 1
0
于 2013-10-06T16:29:33.203 回答
0

Mysql2 #query 方法返回类型为“Mysql2::Result”的对象。

你可以在这里看到课程:

results.class => Mysql2::Result

您可以在此处获取数组:

results.to_a => [{"COUNT(*)"=>26797}]

而且,如果您只想要整数值:

results.to_a[0]["COUNT(*)"] => 26797

重命名您的计数 ('COUNT(*) as "sms_count"') 将导致更易读的结果。

于 2013-10-06T15:53:41.057 回答