Как получить строки в виде массивов (а не хэшей) в Sequel ORM?

В 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"}]

Есть ли встроенный в Sequel способ вместо этого создать массив массивов строк, где каждая строка представляет собой массив только значений в каждой строке в порядке, указанном в запросе? Как работает 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]]

person jwfearn    schedule 21.04.2011    source источник


Ответы (5)


Если вам нужен просто массив массивов значений...

DB['select * from T'].map { |h| h.values }

кажется работает

ОБНОВЛЕНИЕ с учетом обновленного требования порядка столбцов, соответствующего порядку запроса...

cols= [:a, :c, :b]
DB[:T].select{cols}.collect{ |h| cols.collect {|c| h[c]}}

не очень красивый, но гарантированный порядок такой же, как и порядок выбора. Кажется, для этого нет встроенной функции. Вы можете сделать запрос на эту функцию.

person Jim Morris    schedule 22.04.2011
comment
Это создает массив, но в отличие от ActiveRecord select_rows порядок столбцов не обязательно соответствует порядку, запрошенному в базовом запросе. Я отредактирую свой вопрос, чтобы указать это требование. - person jwfearn; 22.04.2011
comment
Я думаю, что если вы хотите гарантировать порядок, вам нужно указать столбцы, которые вы хотите получить, по порядку, используя dataset#select{[columns,..]}, я обновлю свой ответ примером. - person Jim Morris; 22.04.2011
comment
К вашему сведению, это, конечно, не удастся, если в вашем наборе результатов есть повторяющиеся имена столбцов: DB['SELECT 1 AS test, 2 AS test'] - person aidan; 26.07.2017

В старых версиях Sequel (до 2.0) некоторые адаптеры имели возможность возвращать массивы вместо хэшей. Но это вызывало множество проблем, им никто не пользовался, и я не хотел его поддерживать, поэтому его удалили. Если вам действительно нужны массивы, вам нужно перейти на уровень соединения и использовать метод, специфичный для соединения:

DB.synchronize do |conn|
  rows = conn.exec('SQL Here') # Hypothetical example code
end

Фактический код, который вам нужен, будет зависеть от используемого вами адаптера.

person Jeremy Evans    schedule 25.04.2011
comment
@jwfeam: Я поддерживаю это. Я не могу стереть улыбку со своего лица с тех пор, как обнаружил ее. Наконец-то что-то, что позволяет мне написать именно тот запрос, который мне нужен, без объединения битов и фрагментов строк SQL. - person Denis de Bernardy; 20.06.2011

БД[:таблица].где().select_map(:id)

person Cris R    schedule 06.05.2016

Я еще не нашел встроенного метода для возврата массива массивов строк, где значения в массивах строк упорядочены по порядку столбцов в исходном запросе. Следующая функция работает*, хотя я подозреваю, что внутренний метод может быть более эффективным:

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 не очень полезна.

person jwfearn    schedule 22.04.2011

Вы пробовали это?

ds = DB['select a, b, c from T'].to_a

не уверен, что это работает, но попробуйте.

person user1903663    schedule 22.02.2014