#ruby #sequel
#ruby #продолжение
Вопрос:
В Sequel ORM для Ruby у Dataset
класса есть all
метод, который создает массив хэшей строк: каждая строка представляет собой хэш с именами столбцов в качестве ключей.
Например, учитывая таблицу T:
a b c
--------------
0 22 "Abe"
1 35 "Betty"
2 58 "Chris"
затем:
ds = DB['select a, b, c from T']
ah = ds.all # Array of row Hashes
должно выдавать:
[{"a":0,"b":22,"c":"Abe"},{"a":1,"b":35,"c":"Betty"},{"a":2,"b":58,"c":"Chris"}]
Есть ли встроенный способ продолжить, чтобы вместо этого создать массив массивов строк, где каждая строка представляет собой массив только значений в каждой строке в порядке, указанном в запросе? Вроде как select_rows
работает в ActiveRecord? Что-то вроде этого:
aa = ds.rows # Array of row Arrays
что привело бы к:
[[0,22,"Abe"],[1,35,"Betty"],[2,58,"Chris"]]
Примечание: выражение:
aa = ds.map { |h| h.values }
создает массив массивов, но порядок значений в строках НЕ гарантированно соответствует порядку, запрошенному в исходном запросе. В этом примере aa
может выглядеть:
[["Abe",0,22],["Betty",1,35],["Chris",2,58]]
Ответ №1:
Старые версии Sequel (до 2.0) имели возможность в некоторых адаптерах возвращать массивы вместо хэшей. Но это вызвало множество проблем, никто им не пользовался, и я не хотел его поддерживать, поэтому он был удален. Если вам действительно нужны массивы, вам нужно опуститься до уровня соединения и использовать метод, специфичный для соединения:
DB.synchronize do |conn|
rows = conn.exec('SQL Here') # Hypothetical example code
end
Фактический код, который вам нужен, будет зависеть от используемого вами адаптера.
Комментарии:
1. @jwfeam: Я поддерживаю это. Я не могу стереть улыбку со своего лица с тех пор, как обнаружил это. Наконец -то, что позволяет мне написать именно тот запрос, который мне нужен, без объединения фрагментов строк SQL.
Ответ №2:
DB[:table].where().select_map(:id)
Комментарии:
1. Должен быть принят ответ.
my_keys = [:a, :b, :c]; DB[:T].select_map(my_keys)
Ответ №3:
Если вам нужен просто массив значений array…
DB['select * from T'].map { |h| h.values }
кажется, работает
ОБНОВЛЕНИЕ с учетом обновленного требования к порядку столбцов, соответствующему порядку запроса…
cols= [:a, :c, :b]
DB[:T].select{cols}.collect{ |h| cols.collect {|c| h[c]}}
не очень красиво, но гарантированный порядок такой же, как порядок выбора.
Похоже, для этого не существует встроенного модуля.
Вы могли бы сделать запрос на эту функцию.
Комментарии:
1. Это создает массив, но, в отличие от ActiveRecord
select_rows
, порядок столбцов не обязательно соответствует порядку, запрошенному в базовом запросе. Я отредактирую свой вопрос, чтобы указать это требование.2. Я думаю, что если вы хотите гарантировать порядок, то вам нужно указать столбцы, которые вы хотите получить, по порядку, используя
dataset#select{[columns,..]}
, я дополню свой ответ примером.3. К вашему сведению, это, конечно, завершится неудачей, если в вашем результирующем наборе будут дублироваться имена столбцов:
DB['SELECT 1 AS test, 2 AS test']
Ответ №4:
Я еще не нашел встроенный метод для возврата массива массивов строк, где значения в массивах строк упорядочены по порядку столбцов в исходном запросе. Следующая функция выполняет * хотя я подозреваю, что внутренний метод мог бы быть более эффективным:
def rows( ds )
ret = []
column_keys = ds.columns # guaranteed to match query order?
ds.all { |row_hash|
row_array = []
column_keys.map { |column_key| row_array << row_hash[column_key] }
ret << row_array
}
ret
end
* Эта функция зависит от порядка массива, возвращаемого Dataset.columns
. Если этот порядок не определен, то эта rows
функция не очень полезна.
Ответ №5:
вы пробовали это?
ds = DB['select a, b, c from T'].to_a
не уверен, что это работает, но попробуйте.