Как бы я использовал slick 3.0, чтобы возвращать по одной строке за раз?

Как бы я построил запрос scala для return одной строки моей таблицы за раз?

Мои таблицы находятся в следующем месте, если они помогают ответить на этот вопрос: Запросы Slick 3.0 (scala) не возвращают данные, пока они не будут запущены несколько раз (я думаю)

 val q5 = for {
  c <- dat.patientsss 
} yield (c.PID, c.Gender, c.Age, c.Ethnicity)

Await.result((db.stream(q5.result).foreach(println)),Duration.Inf)

но вместо печати мне нужно вернуть каждый.


person S2C    schedule 01.07.2015    source источник
comment
что вы подразумеваете под возвратом каждого? Вы имеете в виду, что хотите, чтобы из запроса возвращалась только одна строка?   -  person bjfletcher    schedule 01.07.2015
comment
да, только один (c.PID, c.Gender, c.Age, c.Ethnicity) за раз   -  person S2C    schedule 02.07.2015
comment
двумя способами: 1. добавить .take(1) в строку dat.patientsss, 2. добавить .head в q5.result. Это гарантирует, что вы получите только первую строку. Это то, о чем вы просили?   -  person bjfletcher    schedule 02.07.2015
comment
вид, за исключением того, что я хочу итерировать по всем строкам одну за другой   -  person S2C    schedule 02.07.2015
comment
Теперь мне любопытно... Почему вы хотите повторять свои результаты, имея базу данных туда и обратно для каждого результата? Есть ли причина не извлекать все строки сразу? Поскольку круговые обращения к базе данных обходятся дорого, обычно желательно иметь как можно меньше круговых обращений.   -  person Roman    schedule 02.07.2015
comment
Мне нужно передать данные из текстового документа в модель машинного обучения. Я использую парсер для чтения данных и преобразования их в базу данных (база данных находится в памяти). Нам нужна база данных, чтобы мы могли выполнять запросы и возвращать настраиваемые данные (например, возраст и этническая принадлежность могут иметь значение, но у нас есть возможность возвращать другие данные, помимо этих или этих, по отдельности, вместо того, чтобы создавать отдельный парсер для каждого настраиваемого запроса. Мне нужно возвращать по одной строке за раз из результатов запроса, потому что они узнают по одной за раз.   -  person S2C    schedule 02.07.2015
comment
Что ж, тогда я предлагаю перейти к решению, которое я разместил ниже. 1. Прочитайте всю информацию из вашей базы данных, 2. Переберите результаты, которые дадут вам каждую строку одну за другой.   -  person Roman    schedule 03.07.2015


Ответы (1)


Отвечать

Вместо этого используйте материализованный результат:

val result = Await.result((db.run(q5.result)), Duration.Inf)

result — это Seq, который содержит все данные о вашем пациенте. Используйте foreach для перебора набора результатов:

result.foreach(r => yourFancyAlgorithm(r))  // r is a single patients data row

Примечание

Await блокирует текущий поток, что делает одну из лучших функций slick устаревшей. Блокировать потоки — это то, чего вы не должны делать. Я настоятельно рекомендую прочитать о Future и Promise в scala.
Приведенный выше пример можно просто записать так:

val result = db.run(q5.result))

result в этом случае будет иметь тип Future[Seq[(yourPatientsData)]]. Чтобы получить доступ к данным, используйте map в результате:

result.map(d => whatever)  // d is of type Seq[(yourPatientsData)]

В ожидании результата остальная часть вашего приложения продолжит свои вычисления и прочее. Наконец, когда результат будет готов, запустится обратный вызов (d => whatever).

person Roman    schedule 01.07.2015
comment
Я не особо уверен, насколько Future будет полезен? Моему алгоритму нужны данные для выполнения каких-либо вычислений, поэтому не придется ли мне использовать Await? Кроме того, предложенный код более или менее работал (с изменениями, конечно;) - person S2C; 04.07.2015