Как вызвать результаты запроса в файле, который соответствует структуре цикла в python

#python #json #postgresql

Вопрос:

Я новичок в python и хочу закончить свой школьный проект.

Моя программа состоит из отображения результатов запроса из моей базы данных postgresql, а затем создания функции, которая форматирует результаты этого запроса в файл JSON.

Мой код :

 import psycopg2
import json
//Allows the connection to the database and displays the results in the terminal
def run(stmt):
    cur = psycopg2.connect(database='x', user='s', password='!', host='1').cursor()
    cur.execute(stmt)
    result = cur.fetchall()
    print(list(result))

//query that displays data from the database
stmt = 'select cast(row_to_json(row) as text) from (SELECT id, nom,  lon, lat FROM  u.b_l_b_s JOIN u.b_s ON b_s.id = b_s_id JOIN u.b_l ON b_l.id = b_l_id JOIN u.b_s_t ON   b_s_t.id = b_s_t_id ) row;'
    run(stmt)

//Output :
[('{"id":370,"nom":"MORO","lon":47.466001,"lat":-18.852607}',),     ('{"id":46,"nom":"NOROE","lon":47.473006,"lat":-18.852907}',),  ('{"id":45,"nom":"ANORO PLAQUE","lon":47.473404,"lat":-18.850003}',)
 

Я хочу, чтобы все данные запроса записывались в цикле (максимум 10) , как это:

  {
   'stations': {
    result['label']: {
    'id': result['id'],
    'nom': result['nom'],
    'position': {
    'lat': result['lat'],
    'lon': result['lon']
                }
            }
    result['label']: {
    'id': result['id'],
    'nom': result['nom'],
    'position': {
    'lat': result['lat'],
    'lon': result['lon']
                }
            }
        }
    }
 

Заранее благодарю тех, кто найдет время ответить на мой вопрос.

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

1. См., в частности, модуль json json.dump .

Ответ №1:

Вы приближаетесь, но, возможно, в конце захотите преобразовать свои ценности. В PostgreSQL есть функции для возврата массива JSON (https://www.postgresql.org/docs/9.3/functions-json.html), но я думаю, что они сложнее, чем вам нужно.

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

 from psycopg2.extras import RealDictCursor

def run(stmt):
    conn = psycopg2.connect(database='x', user='s', password='!', host='1')
    cur = conn.cursor(cursor_factory=RealDictCursor)
    ...
 

Далее вас попросят вернуть только 10 записей. Вы можете сделать это в своем запросе, добавив LIMIT 10 в конце

SELECT id, nom, lon, lat FROM u.b_l_b_s JOIN u.b_s ON b_s.id = b_s_id JOIN u.b_l ON b_l.id = b_l_id JOIN u.b_s_t ON b_s_t.id = b_s_t_id LIMIT 10

или вы можете сделать это при извлечении с помощью fetchmany вместо fetchall. Это особенно хорошо, если стол большой.

result = cur.fetchmany(10)

Когда вы используете RealDictCursor, ваши результаты выглядят немного странно, это список объектов «RealDictRow», но они все равно ведут себя как словарь.

 >>> result
[RealDictRow([('id', 370), ...etc

>>> result[0]['id']
370
 

Итак, у вас есть ваши десять записей, и они находятся в списке словарей. Теперь вы можете просмотреть список. Предполагая, что вы возвращаете переменную с именем final_result , это может выглядеть так:

 final_result = {'stations': []}  # we collect each result as an element of this list

for record in result:
    final_result['stations'].append(record) 

# finally, we convert it to JSON
json.dumps(final_result)