SQL float columns: select "where x = 2.0" works, but "where x = 2.1" does not - mysql

I have a Ruby on Rails app with a model Project, which has an attribute wcag_version of type float.
I have a record with wcag_version = 2 and one with wcag_version = 2.1:
What I noticed is that Rails finds the record with wcag_version = 2 using Project.where(wcag_version: 2.0):
[4] pry(#<WcagElementsController>)> Project.where(wcag_version: 2.0)
=> [
[0] #<Project:0x007f9fa900c6e8> { :id => 1 ... }
But it doesn't find the record with wcag_version = 2.1 using Project.where(wcag_version: 2.1):
[5] pry(#<WcagElementsController>)> Project.where(wcag_version: 2.1)
=> []
It seems to be an SQL issue, not a Rails issue though. The generated SQL is:
[6] pry(#<WcagElementsController>)> Project.where(wcag_version: 2.1).to_sql
=> "SELECT `projects`.* FROM `projects` WHERE `projects`.`wcag_version` = 2.1 ORDER BY `projects`.`name` ASC"
Which doesn't return anything either if I execute it manually directly on the database:
What's going on here? I'm using MySQL by the way.

Dealing with Rails, it seems that I can work around the problem like this:
Project.all.each do |project|
if project.wcag_version >= reference_criterion.wcag_version
# Do stuff
end
end
While this is less performant, it saves me a lot of headache.
For sake of completeness, here's the original code:
Project.where("wcag_version >= #{reference_criterion.wcag_version}").each do |project|
# Do stuff
end

Related

How can I configure the rails console to show the line of code where a sql gets executed?

Currently when I run a method in the rails console it shows all the sql queries but I would like it to also show where in the code the sql is being called. How can I do that?
Running ActiveRecord::Base.verbose_query_logs = true in the console solved this issue for me. I found the info here
Pry (http://pry.github.com/) might help. There is a show-source method that will do this when run from the console. Here is an example I did locally.
rails c
DEBUG: Chewy strategies stack: [2] <- urgent # /Users/jmlockl2/.rvm/gems/ruby-2.3.1#ask/gems/chewy-0.9.0/lib/chewy/railtie.rb:49
Loading development environment (Rails 3.2.22.5)
2.3.1 :001 > pry
[1] pry(main)> q=Question.last
Question Load (0.2ms) SELECT `questions`.* FROM `questions` ORDER BY `questions`.`id` DESC LIMIT 1
=> ...
[2] pry(main)> q.email
User Load (0.2ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 535441 LIMIT 1
=> "email#gmail.com"
[3] pry(main)> show-source q.email
[3] pry(main)> show-source q.email
From: /Users/...question.rb # line 564:
Number of lines: 3
Owner: Question
Visibility: public
def email
self.submitter.present? ? self.submitter.email : ''
end
[4] pry(main)>
Hope this helps!

Retrieving array from MySQL

I'm not using sqlite3 gem
I'm using mysql2 gem
I'm retrieving data from MySQL database given that it meets the condition of a certain event type and severity. However, it returns only one row instead of an array of results. It really puzzles me. Shouldnt .map return an array?
result = connect.query("SELECT * FROM data WHERE event_type = 'ALARM_OPENED' AND severity = '2'")
equipments = result.map do |record|
[
record['sourcetime'].strftime('%H:%M:%S'),
record['equipment_id'],
record['description']
]
end
p equipments
I had misread your question...I think what you are looking for is in here.
UPDATE
You can use each instead, like this:
#!/usr/bin/env ruby
require 'mysql2'
connect= Mysql2::Client.new(:host => '', :username => '', :password => '', :database => '')
equipments = []
result = connect.query("SELECT * FROM data WHERE event_type = 'ALARM_OPENED' AND severity = '2'", :symbolize_keys => true).each do |row|
equipments << [
row[:sourcetime].strftime('%H:%M:%S'),
row[:equipment_id],
row[:description]
]
end
puts "#equipments {equipments}"
EDITED:
I forgot to add .each at the end of the query. So it was returning the initialized empty array instead.
You must need to change your sql statement :
result = connect.query("SELECT * FROM data WHERE event_type = 'ALARM_OPENED' AND severity = '2'", :as => :array)

How to return MySQL query results from EventMachine?

I'm trying to use EM::Synchrony to speed up my queries by making them async. Following along with the examples from the github page here I'm making 2 asynchronous queries:
EventMachine.synchrony do
db = EventMachine::Synchrony::ConnectionPool.new(size: 2) do
Mysql2::EM::Client.new(
:host => config[:server],
:username => config[:user],
:password => config[:pwd],
:database => config[:db_name]
)
end
multi = EventMachine::Synchrony::Multi.new
multi.add :a, db.aquery("
select count(distinct userid) from my_table
where date = '2013-09-28'
")
multi.add :b, db.aquery("
select count(distinct userid) from my_table
where date = '2013-09-27'
")
res = multi.perform
puts res
# p "Look ma, no callbacks, and parallel MySQL requests!"
# p res.responses[:callback][0]
EventMachine.stop
end
> #<EventMachine::Synchrony::Multi:0x00000001eb8da8>
My question is how do I setup a callback to actually get the values returned by the queries? What I would like to do is once the queries are finished, aggregate them back together and write to another table or csv or whatever. Thanks.
Maybe you don't need Synchrony? They are async anyway. https://github.com/brianmario/mysql2#eventmachine
But if you do need then probably the answer is
res.responses[:callback][:a]
res.responses[:callback][:b]
https://github.com/igrigorik/em-synchrony/blob/master/lib/em-synchrony/em-multi.rb#L17
What I found is that the following code will give me the results from the queries:
res.responses[:callback].each do
|obj|
obj[1].callback do
|rows|
rows.each do
|row|
puts row.inspect
end
end
end
$ruby async_mysql.rb
{"count(distinct ui)"=>159}
{"count(distinct ui)"=>168}

Cannot search on a particular index

Model:
class TechRequest < ActiveRecord::Base
...
define_index do
...
indexes :hot_request
indexes :status_id, :as => :current_status_id
...
has :hot_request , :as => :hot_request
set_property :delta => true
end
DB:
hot_request - tinyint(1)
When I execute the controller code-
#query_string = '(#hot_request 1)(#current_status_id 1 | 2 | 3)'
#tech_requests = TechRequest.search #query_string, :match_mode => :extended
the following error is thrown up:
ThinkingSphinx::SphinxError: index tech_request_core,tech_request_delta: query error: no field 'tech_hot_request' found in schema
from D:/Current/TechAssistTest/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/search.rb:392:in 'populate'
from D:/Current/TechAssistTest/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/search.rb:508:in 'call'
from D:/Current/TechAssistTest/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/search.rb:508:in 'retry_on_stale_index'
from D:/Current/TechAssistTest/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/search.rb:379:in 'populate'
from D:/Current/TechAssistTest/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/search.rb:167:in 'method_missing'
from D:/ruby/lib/ruby/1.8/irb.rb:302:in 'output_value'
from D:/ruby/lib/ruby/1.8/irb.rb:151:in 'eval_input'
from D:/ruby/lib/ruby/1.8/irb.rb:263:in 'signal_status'
from D:/ruby/lib/ruby/1.8/irb.rb:147:in 'eval_input'
from D:/ruby/lib/ruby/1.8/irb.rb:146:in 'eval_input'
from D:/ruby/lib/ruby/1.8/irb.rb:70:in 'start'
from D:/ruby/lib/ruby/1.8/irb.rb:69:in 'catch'
from D:/ruby/lib/ruby/1.8/irb.rb:69:in 'start'
from D:/ruby/bin/irb:13
The search works fine when I use hot_request as an attribute. The
search also works fine when I use #query_string = '(#current_status_id 1 | 2 | 3)'.
I've just run into similar looking problems - there are two possible reasons why this errors that I can see. First is that according to http://sphinxsearch.com/forum/view.html?id=2103 you can use an sql column as a field or an attribute but not both (without cloning it). The other, which had me baffled for a while, is that you may need to specify the type - so if hot_request is actually an integer, you probably need to have something like
indexes hot_request :as => hr, :type => :integer
or you get that cryptic error message
Hope this helps someone ...

Ruby On Rails: Testing deletes tables

I'm creating an application in RoR and I'm implementing unit testing in all my models.
When I run every test on his own (by running ruby test/unit/some_test.rb) all tests are successful.
But when I run all tests together (by running rake test:units) some tables from both databases (development e test) are deleted.
I'm using raw SQL (mysql) do create tables because I need composite primary keys and physical constraints so I figured it would be the best. Maybe this be the cause?
All my tests are in this form:
require File.dirname(FILE) + '/../test_helper'
require File.dirname(FILE) + '/../../app/models/order'
class OrderTestCase < Test::Unit::TestCase
def setup
#order = Order.new(
:user_id => 1,
:total => 10.23,
:date => Date.today,
:status => 'processing',
:date_concluded => Date.today,
:user_address_user_id => 3,
:user_address_address_id => 5,
:creation_date => Date.today,
:update_date => Date.today
)
end
################ Happy Path
def test_happy_path
assert #order.valid?, #order.errors.full_messages
end
...
The errors I get when running the tests are something like this:
3) Error:
test_empty_is_primary(AddressTestCase):
ActiveRecord::StatementInvalid: Mysql::Error: Table 'shopshop_enterprise_test.addresses' doesn't exist: SHOW FIELDS FROM addresses
/test/unit/address_test.rb:9:in new'
/test/unit/address_test.rb:9:insetup'
Any guesses?
Thanks!
PS: When using postgres as the database engine, everything works fine with rake test:units! (of course, with the correct changes so the sql statements can work with postgres)