I am trying to connect to MySQL suing DBI. I am following Using the Ruby DBI Module documentation.
Here is my code:
require 'dbi'
begin
dbh = DBI.connect("DBI:Mysql:<db_name>:<mysql_hostname>", "<mysql_user>", "<mysql_password>")
row = dbh.select_one("SELECT VERSION()")
puts "Server version: " + row[0]
rescue DBI::DatabaseError => e
puts "Something went wrong connecting the database"
puts e.errstr
end
sth = dbh.prepare("SHOW TABLES")
sth.execute
while row = sth.fetch
puts row
end
sth.finish
dbh.disconnect
This code fails with below error:
Server version: 5.6.13-log
/home/user/dbi_testing.rb:14:in `puts': undefined method `to_ary' for nil:NilClass (NoMethodError)
In above error, I am printing the MySQL version (Server version: 5.6.13-log) just to ensure that I have good working connection to the DB.
This error is thrown by the while loop above. So I changed it to below:
sth.fetch do |row|
puts row
end
And still get the exact same error.
So it means either sth.fetch method does not exists or something is wrong with the way I am accessing it.
Could you help me resolving this error.
UPDATE: I made some progress, if I put it as below, the I can see the tables:
sth.fetch_hash do |row|
puts row
end
The output is:
Server version: 5.6.13-log
{"Tables_in_mstrmd"=>"DSSCSADDRESS"}
{"Tables_in_mstrmd"=>"DSSCSBADGETB"}
{"Tables_in_mstrmd"=>"DSSCSCONTACT"}
{"Tables_in_mstrmd"=>"DSSCSDEVCKEY"}
{"Tables_in_mstrmd"=>"DSSCSPSNLZTN"}
{"Tables_in_mstrmd"=>"DSSCSRCOLCON"}
{"Tables_in_mstrmd"=>"DSSCSRINSTRG"}
{"Tables_in_mstrmd"=>"DSSCSSUBINST"}
{"Tables_in_mstrmd"=>"DSSCSSYSPROP"}
{"Tables_in_mstrmd"=>"DSSMDJRNINFO"}
{"Tables_in_mstrmd"=>"DSSMDJRNLNKS"}
{"Tables_in_mstrmd"=>"DSSMDJRNOBJC"}
{"Tables_in_mstrmd"=>"DSSMDJRNOBJD"}
{"Tables_in_mstrmd"=>"DSSMDJRNOBJS"}
{"Tables_in_mstrmd"=>"DSSMDLNKITEM"}
{"Tables_in_mstrmd"=>"DSSMDLNKPROP"}
{"Tables_in_mstrmd"=>"DSSMDOBJBLOB"}
{"Tables_in_mstrmd"=>"DSSMDOBJCMNT"}
{"Tables_in_mstrmd"=>"DSSMDOBJDEF2"}
{"Tables_in_mstrmd"=>"DSSMDOBJDEFN"}
{"Tables_in_mstrmd"=>"DSSMDOBJDEPN"}
{"Tables_in_mstrmd"=>"DSSMDOBJINFO"}
{"Tables_in_mstrmd"=>"DSSMDOBJLOCK"}
{"Tables_in_mstrmd"=>"DSSMDOBJPROP"}
{"Tables_in_mstrmd"=>"DSSMDOBJSECU"}
{"Tables_in_mstrmd"=>"DSSMDOBJTRNS"}
{"Tables_in_mstrmd"=>"DSSMDSYSPROP"}
{"Tables_in_mstrmd"=>"DSSMDUSRACCT"}
So, I am able to see the tables when I use sth.fetch_hash. Then what is wrong with sth.fetch?
Any pointers would be of immense help.
UPDATE (WORKAROUND):
I ran puts sth.methods.sort and here is the output:
fetch
fetch_all
fetch_array
fetch_hash
fetch_many
fetch_scroll
fetchable?
I changed sth.fetch to sth.fetch_array and now I am able to see the tables Fine.
The credit goes to a this comment by #philant
So, in a way my question has got a workaround.
But I still want to know why the method sth.fetch did not work ? Any explanation would be really helpful.
Related
i've looked into previous questions which look similar to my problem, nothing seems to be related.
After doing the following query:
Runner::Models::Job.where(:id => job_id)
I get an exception, it happens once in a while:
Mysql2::Error: MySQL server has gone away: SELECT jobs.* FROM jobs WHERE jobs.id = 7507 LIMIT 1
I use puma, and in config.ru i am using:
use ActiveRecord::ConnectionAdapters::ConnectionManagement
The thing is that this error always happens in the same place, and i cant figure out why is it happening, i've checked memory, cpu, etc'.., all seem normal.
Maybe someone will have an idea.
thanks !
Write your Resque task like this:
class MyTask
def self.perform
ActiveRecord::Base.verify_active_connections!
# rest of your code
end
end
see more details here: https://github.com/resque/resque/wiki/FAQ#how-do-you-work-around-the-mysql-server-has-gone-away-error-
Running django via gunicorn to RDS (AWS mysql), I'm seeing this error in my gunicorn logs:
Exception _mysql_exceptions.ProgrammingError: (2014, "Commands out of sync; you can't run this command now") in <bound method Cursor.__del__ of <MySQLdb.cursors.Cursor object at 0x690ecd0>> ignored
I can't reliably reproduce it yet, nor can I track down the underlying code that's causing it.
I am using raw cursors in some places, following this pattern:
cursor = connections['read_only'].cursor()
sql = "select username from auth_user;"
cursor.execute(sql)
rows = cursor.fetchall()
usernames = []
for row in rows:
usernames.append(row[0])
In some places I immediately reuse the cursor for another query execute() / fetchall() pattern. Sometimes I don't.
I also use raw manager queries in some place.
I'm not explicitly closing cursors, but I don't believe that I should.
Other than that: I'm not using any stored procedures, no init_command parameters, nor anything else indicated in the other answers I've seen posted here.
Any ideas or suggestions for how to debug would be appreciated.
Check out https://code.djangoproject.com/ticket/17289
you'll need to do something like:
while cursor.nextset() is not None:
if verbose:
print "rows modified %s" % cursor.rowcount
I am encountering the 'mysql has gone away' error in Ruby after a certain amount of time that the script has been running.
I want to try to tell the mysql gem to auto-reconnect when the connection is lost.
My current code looks like the following:
def self.connect()
begin
if !##dbh.nil?
self.disconnect
end
##dbh = Mysql.real_connect(##server, ##user, ##pass, ##db)
puts "[+] Connected to the " + ##db + " database with user '" + ##user + "'"
rescue Mysql::Error => e
# log error
end
end
The following guide [0] says that the mysql gem has a 'reconnect' object variable, however, I am unsure of how to use it within my code.
How do I implement this option into the code above?
Thanks in advance,
Ryan
[0] http://www.tmtm.org/en/mysql/ruby/
EDIT ---
OK. I think I have figured it out.
I need to add ##dbh.reconnect = true after the ##dbh = Mysql.real_connect(##server, ##user, ##pass, ##db) line.
Note: According to a 'nice' chapy on IRC the mysql gem may not be the best Ruby gem to use.
If you're starting on a new project, the mysql2 gem is the way to go. It's an enormous improvement over the old version.
An attempt to Ruby-ize your example is:
def connect
begin
if (#dbh)
self.disconnect
end
#dbh = Mysql.real_connect(#server, #user, #pass, #db)
puts "[+] Connected to the #{#db} database with user '#{#user}'"
rescue Mysql::Error => e
# log error
end
end
The reason for using traditional # variables is you can use attr_accessor if you design your interface properly.
It's better to use a singleton instance than to wreck around with a singleton class. For instance:
class MyApp
def self.db
#db ||= Database.new
end
class Database
# Instance methods like initialize, connect, disconnect, etc.
end
end
You can use this like:
MyApp.db.connect
The advantage of using an instance of a class instead of a class directly is you can support more than one connection at a time.
What I want to do is something like this:
function registerUser($username, $password){
$this->db->insert('tblUsers', array('username'=>$username, 'password'=>md5($password)));
if($this->db->_error_number()==1062){
return "DUPLICATE";
}
return true;
}
However, at the moment if there is a duplicate key then its not letting me get to the _error_number() bit. Its displaying an error like this:
How do I stop codeigniter from bailing with an error and passing the error number to me to deal with appropriately?
Thanks
You can access MySQL error messages in Codeigniter using:
$this->db->_error_message();
Apparently DB_DEBUG needs to be set to false in the database config file:
Ensure DB_DEBUG is set to FALSE in the database config file, or
execution will halt when a mysql error occurs (it does not get thrown,
it justs exits from the php interpreter)
Link: http://codeigniter.com/forums/viewthread/79950/#413830
Suggestion:
$orig_db_debug = $this->db->db_debug;
$this->db->db_debug = FALSE;
RUN QUERY HERE
$this->db->db_debug = $orig_db_debug;
I've been searching all over for tips on this and have not really had any luck so far. With the mysql2 gem, trying to execute a stored procedure that returns multiple result sets gives me an unable to return results in this context error. I found someone had suggested to use the mysql gem instead (which I can't find an explanation of what's different between the two and what I might encounter by switching), and with that I've had more progress.
Here's what I have so far:
>> db = ActiveRecord::Base.connection.raw_connection
=> #<Mysql:0x1056ae3d8>
>> ActiveRecord::Base.connection.select_all("CALL p_rpt_test('', '');")
=> [{"Header"=>"Client,Project,Type,Due Date,Assigned To"}]
>> db.more_results?
=> true
>> db.next_result
Mysql::Error: Commands out of sync; you can't run this command now
from (irb):3:in `next_result'
from (irb):3
Does anyone know of a way to get this to work, with mysql2 or mysql gems? The app is running rails 3.0.1.
Ok well I have no figured out how to get AR to do this so I've ended up just going low level and using the mysql driver itself, which mostly works...
data = Array.new
db = ActiveRecord::Base.connection.raw_connection
header = db.query("CALL #{self.proc}(#{args});")
header.each {|r| data << r}
if db.next_result
rows = db.store_result
rows.each {|r| data << r}
end
ActiveRecord::Base.connection.reconnect!
It works, but I can't imagine there's not a better way. Also I have to reconnect after this or I get an error on the next query, and I haven't found a way to properly close the session. Oh and I have to use the mysql gem and not mysql2.
Grrrrr.
We can use header.to_hash to get an array of hash, or header.rows to get an array of array.
Follow this http://api.rubyonrails.org/classes/ActiveRecord/Result.html