вернуть таблицу SQL как JSON в Python - PullRequest
37 голосов
/ 20 июля 2010

Я играю с небольшим веб-приложением в web.py и настраиваю URL для возврата объекта JSON.Каков наилучший способ конвертировать таблицу SQL в JSON с использованием Python?

Ответы [ 9 ]

67 голосов
/ 20 июля 2010

Вот действительно хороший пример питонского способа сделать это :

import json
import psycopg2

def db(database_name='pepe'):
    return psycopg2.connect(database=database_name)

def query_db(query, args=(), one=False):
    cur = db().cursor()
    cur.execute(query, args)
    r = [dict((cur.description[i][0], value) \
               for i, value in enumerate(row)) for row in cur.fetchall()]
    cur.connection.close()
    return (r[0] if r else None) if one else r

my_query = query_db("select * from majorroadstiger limit %s", (3,))

json_output = json.dumps(my_query)

Вы получаете массив объектов JSON:

>>> json_output
'[{"divroad": "N", "featcat": null, "countyfp": "001",...

Илисо следующим:

>>> j2 = query_db("select * from majorroadstiger where fullname= %s limit %s",\
 ("Mission Blvd", 1), one=True)

вы получите один объект JSON:

>>> j2 = json.dumps(j2)
>>> j2
'{"divroad": "N", "featcat": null, "countyfp": "001",...
20 голосов
/ 05 августа 2013
import sqlite3
import json

DB = "./the_database.db"

def get_all_users( json_str = False ):
    conn = sqlite3.connect( DB )
    conn.row_factory = sqlite3.Row # This enables column access by name: row['column_name'] 
    db = conn.cursor()

    rows = db.execute('''
    SELECT * from Users
    ''').fetchall()

    conn.commit()
    conn.close()

    if json_str:
        return json.dumps( [dict(ix) for ix in rows] ) #CREATE JSON

    return rows

Вызов метода no json ...

print get_all_users()

печать:

[(1, u'orvar', u'password123'), (2, u'kalle', u'password123')]

Вызов метода с помощью json ...

print get_all_users( json_str = True )

печать:

[{"password": "password123", "id": 1, "name": "orvar"}, {"password": "password123", "id": 2, "name": "kalle"}]
18 голосов
/ 20 июля 2010

Лично я предпочитаю SQLObject для такого рода вещей.Я адаптировал какой-то быстрый и грязный тестовый код, который мне нужно было получить:

import simplejson

from sqlobject import *

# Replace this with the URI for your actual database
connection = connectionForURI('sqlite:/:memory:')
sqlhub.processConnection = connection

# This defines the columns for your database table. See SQLObject docs for how it
# does its conversions for class attributes <-> database columns (underscores to camel
# case, generally)

class Song(SQLObject):

    name = StringCol()
    artist = StringCol()
    album = StringCol()

# Create fake data for demo - this is not needed for the real thing
def MakeFakeDB():
    Song.createTable()
    s1 = Song(name="B Song",
              artist="Artist1",
              album="Album1")
    s2 = Song(name="A Song",
              artist="Artist2",
              album="Album2")

def Main():
    # This is an iterable, not a list
    all_songs = Song.select().orderBy(Song.q.name)

    songs_as_dict = []

    for song in all_songs:
        song_as_dict = {
            'name' : song.name,
            'artist' : song.artist,
            'album' : song.album}
        songs_as_dict.append(song_as_dict)

    print simplejson.dumps(songs_as_dict)


if __name__ == "__main__":
    MakeFakeDB()
    Main()
13 голосов
/ 20 июля 2010

Дополнительная информация о том, как вы будете работать с вашими данными, прежде чем передавать их, может помочь.Модуль json предоставляет методы dump (s) и load (s), которые помогут, если вы используете версию 2.6 или новее: http://docs.python.org/library/json.html.

- EDITED -

Не зная, какойбиблиотеки, которые вы используете, я не могу вам точно сказать, найдете ли вы такой метод.Как правило, я обрабатываю результаты запроса следующим образом (примеры с kinterbasdb, потому что это то, с чем мы сейчас работаем):

qry = "Select Id, Name, Artist, Album From MP3s Order By Name, Artist"
# Assumes conn is a database connection.
cursor = conn.cursor()
cursor.execute(qry)
rows = [x for x in cursor]
cols = [x[0] for x in cursor.description]
songs = []
for row in rows:
  song = {}
  for prop, val in zip(cols, row):
    song[prop] = val
  songs.append(song)
# Create a string representation of your array of songs.
songsJSON = json.dumps(songs)

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

5 голосов
/ 04 мая 2016

Я собрал короткий скрипт, который выводит все данные из всех таблиц в виде подсказок имени столбца: значение. В отличие от других решений, он не требует никакой информации о том, что такое таблицы или столбцы, он просто находит все и выдает его. Надеюсь, кто-то найдет это полезным!

from contextlib import closing
from datetime import datetime
import json
import MySQLdb
DB_NAME = 'x'
DB_USER = 'y'
DB_PASS = 'z'

def get_tables(cursor):
    cursor.execute('SHOW tables')
    return [r[0] for r in cursor.fetchall()] 

def get_rows_as_dicts(cursor, table):
    cursor.execute('select * from {}'.format(table))
    columns = [d[0] for d in cursor.description]
    return [dict(zip(columns, row)) for row in cursor.fetchall()]

def dump_date(thing):
    if isinstance(thing, datetime):
        return thing.isoformat()
    return str(thing)


with closing(MySQLdb.connect(user=DB_USER, passwd=DB_PASS, db=DB_NAME)) as conn, closing(conn.cursor()) as cursor:
    dump = {}
    for table in get_tables(cursor):
        dump[table] = get_rows_as_dicts(cursor, table)
    print(json.dumps(dump, default=dump_date, indent=2))
3 голосов
/ 18 октября 2017

никто, кажется, не предлагал вариант получения JSON напрямую с сервера Postgresql, используя возможность JSON postgres https://www.postgresql.org/docs/9.4/static/functions-json.html

Нет анализа, циклического или какого-либо потребления памяти на стороне Python, что вы можетеочень хочется учесть, имеете ли вы дело с 100 000 или миллионами строк.

from django.db import connection

sql = 'SELECT to_json(result) FROM (SELECT * FROM TABLE table) result)'
with connection.cursor() as cursor:
  cursor.execute(sql)
  output = cursor.fetchall()

таблица типа:

id, value
----------
1     3
2     7

вернет объект JSON Python

[{"id": 1, "value": 3},{"id":2, "value": 7}]

Затем используйте json.dumps для вывода в виде строки JSON

2 голосов
/ 18 января 2017

Я бы дополнил Ответ Демза версией psycopg2:

import psycopg2 
import psycopg2.extras
import json
connection = psycopg2.connect(dbname=_cdatabase, host=_chost, port=_cport , user=_cuser, password=_cpassword)
cursor = connection.cursor(cursor_factory=psycopg2.extras.DictCursor) # This line allows dictionary access.
#select some records into "rows"
jsonout= json.dumps([dict(ix) for ix in rows])
1 голос
/ 16 февраля 2018

Самый простой способ,

используйте json.dumps, но если для его datetime потребуется проанализировать datetime в сериализаторе json.

вот мой,

import MySQLdb, re, json
from datetime import date, datetime

def json_serial(obj):
    """JSON serializer for objects not serializable by default json code"""

    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    raise TypeError ("Type %s not serializable" % type(obj))

conn = MySQLdb.connect(instance)
curr = conn.cursor()
curr.execute("SELECT * FROM `assets`")
data = curr.fetchall()
print json.dumps(data, default=json_serial)

вернет JSON DAMP

еще один простой метод без JSON-дампов , здесь получите заголовок и используйте zip для сопоставления с каждым окончательно сделанным им как json, но это не меняет datetime на json serializer ...

data_json = []
header = [i[0] for i in curr.description]
data = curr.fetchall()
for i in data:
    data_json.append(dict(zip(header, i)))
print data_json
0 голосов
/ 25 марта 2019

Если вы используете MSSQL Server 2008 и выше, вы можете выбрать выполнение SELECT для возврата json, используя FOR JSON AUTO условие E.G

SELECT name, surname FROM users FOR JSON AUTO

Вернет Json как

[{"name": "John" }, {"name": "Jane","surname": "Doe" }, {"name": "Foo","surname": "Samantha" }]

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