Функция для возврата результатов запроса snowflake в виде объекта json

#python #sql #snowflake-cloud-data-platform

Вопрос:

Допустим, у меня есть запрос, который я выполняю в SNOWFLAKE:

 select years from date;
 

Который возвращает набор данных, который выглядит следующим образом:

 1984
1985
1986
....
2019
2020
2021
 

Я пытаюсь вернуть объект JSON, который выглядит следующим образом:

 ["m-1980", "m-1981"..., "m-2021"]
 

В моей функции чего-то не хватает?

 import psycopg2
import json
import snowflake.connector as sf

def get_lyear():
    orig = sf.cursor()          #set the cursor object
    orig.execute('''select distinct year from schema.years''')
    row_headers=[x[0] for x in orig.description] #extract headers
    orig_json = orig.fetchall()
    converted_data=[]
    for i in orig_json:
        converted_data.append(dict(zip(rowheaders,i)))
    return json.dumps(converted_data)
 

Заранее спасибо.

Ответ №1:

Использование ARRAY_AGG:

 SELECT ARRAY_AGG(DISTINCT 'm-' || years::TEXT) AS res
FROM date
 

или:

 SELECT ARRAYAGG('m-' || years::TEXT) WITHIN GROUP(ORDER BY years) AS res
FROM (SELECT DISTINCT years FROM dates);
 

Выход:

введите описание изображения здесь

Комментарии:

1. Спасибо, Лукаш. По какой причине вы хотите использовать массив? Вы случайно не знаете, правильно ли выглядит остальная часть моего кода? (Кстати, большое спасибо)

2. Я не понимаю вопроса в комментарии «По какой причине вы хотите использовать массив?». Разве не об этом спрашивается в первоначальном вопросе?

3. извините @FelipeHoffa — я запутался. мне было интересно, почему он использовал агрегатную функцию массива….

4. @JohnWick Существует две функции agg для полуструктурированной агрегации данных . Здесь мы строим массив, поэтому я использовал ARRAY_AGG.

5. ty @LukaszSzozda

Ответ №2:

Я бы предпочел изменить предлагаемое решение, чтобы определить размер выходного столбца после выполнения приведения года в виде строки:

 SELECT ARRAY_AGG(DISTINCT 'm-' || years::TEXT**(6)**) AS res
FROM date
 

или

 SELECT ARRAYAGG('m-' || years::TEXT**(6)**) WITHIN GROUP(ORDER BY years) AS res
FROM (SELECT DISTINCT years FROM dates);