Rails 3 exécute une requête SQL personnalisée sans modèle


105

J'ai besoin d'écrire un script ruby ​​autonome qui est censé traiter la base de données. J'ai utilisé le code donné ci-dessous dans les rails 3

@connection = ActiveRecord::Base.establish_connection(
:adapter => "mysql2",
:host => "localhost",
:database => "siteconfig_development",
:username => "root",
:password => "root123"
)

results = @connection.execute("select * from users")
results.each do |row|
puts row[0]
end

mais obtenir une erreur: -

`<main>': undefined method `execute' for #<ActiveRecord::ConnectionAdapters::ConnectionPool:0x00000002867548> (NoMethodError)

ce qui me manque ici?

SOLUTION

Après avoir obtenu la solution de denis-bu, je l'ai utilisée de la manière suivante et cela a également fonctionné.

@connection = ActiveRecord::Base.establish_connection(
            :adapter => "mysql2",
            :host => "localhost",
            :database => "siteconfig_development",
            :username => "root",
            :password => "root123"
)

sql = "SELECT * from users"
@result = @connection.connection.execute(sql);
@result.each(:as => :hash) do |row| 
   puts row["email"] 
end

Réponses:



100
connection = ActiveRecord::Base.connection
connection.execute("SQL query") 

8
Dans ce cas, connection = ActiveRecord :: Base.connection; connection.execute ("requête SQL") fonctionnerait. Moins de frappe!
Watusimoto

16
Ou justeActiveRecord::Base.connection.execute("SQL query")
Kasper Grubbe

3
Cette connexion devra peut-être être retournée au pool de connexions par la suite pour éviter les problèmes de thread: ActiveRecord::Base.connection_pool.checkin(connection) apidock.com/rails/ActiveRecord/ConnectionAdapters/…
lee

35

Je recommanderais d'utiliser ActiveRecord::Base.connection.exec_queryau lieu de ActiveRecord::Base.connection.executequi renvoie un ActiveRecord::Result(disponible dans les rails 3.1+) qui est un peu plus facile à utiliser .

Ensuite , vous pouvez y accéder à divers le résultat de diverses manières comme .rows, .eachou.to_hash

À partir de la documentation :

result = ActiveRecord::Base.connection.exec_query('SELECT id, title, body FROM posts')
result # => #<ActiveRecord::Result:0xdeadbeef>


# Get the column names of the result:
result.columns
# => ["id", "title", "body"]

# Get the record values of the result:
result.rows
# => [[1, "title_1", "body_1"],
      [2, "title_2", "body_2"],
      ...
     ]

# Get an array of hashes representing the result (column => value):
result.to_hash
# => [{"id" => 1, "title" => "title_1", "body" => "body_1"},
      {"id" => 2, "title" => "title_2", "body" => "body_2"},
      ...
     ]

# ActiveRecord::Result also includes Enumerable.
result.each do |row|
  puts row['title'] + " " + row['body']
end

note: copié ma réponse d' ici


1
Comme indiqué, exec_query renvoie les résultats réels - ce que je veux, tandis que execute ne renvoie que des informations d'état.
Paul Chernoch

24

Vous pouvez également utiliser find_by_sql

# A simple SQL query spanning multiple tables
Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
> [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]

mon script est en dehors de l'application des rails, donc je ne pense pas que find_by_sql fonctionnerait.
neeraj

4
tu as raison, j'ai lu ta question trop vite. Cette réponse peut aider d'autres personnes qui accèdent à cette page en fonction du titre de votre question.
montrealmike

comment obtenir non pas un tableau mais une relation?
Малъ Скрылевъ

4

Que dis-tu de ça :

@client = TinyTds::Client.new(
      :adapter => 'mysql2',
      :host => 'host',
      :database => 'siteconfig_development',
      :username => 'username',
      :password => 'password'

sql = "SELECT * FROM users"

result = @client.execute(sql)

results.each do |row|
puts row[0]
end

Vous devez avoir installé TinyTds gem, puisque vous ne l'avez pas spécifié dans votre question, je n'ai pas utilisé Active Record


1
Bien sûr, TinyTds est un tout autre joyau ... Ce n'est pas ActiveRecord. Pour l'utiliser, vous devez l'installer séparément.
denis-bu

1
Je ne veux pas utiliser de GEM supplémentaire tant que mysql2 et active-record sont disponibles
neeraj

Bien, vous devriez le mentionner dans votre question (tag / titre)
fourmi

2
TinyTDS fonctionne avec MSSQL et Sybase, il ne fonctionne pas avec MySQL. ant: Vous devriez le mentionner dans votre réponse et ne pas supposer que l'OP utilise le même SGBD de niche que vous.
cliffordheath
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.