在python中将SQL表作为JSON返回

Aar*_*die 40 python sql json

我正在使用web.py中的一个小型web应用程序,并且正在设置一个url来返回一个JSON对象.使用python将SQL表转换为JSON的最佳方法是什么?

unm*_*ted 72

这是一个非常好的pythonic方法的例子:

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)
Run Code Online (Sandbox Code Playgroud)

您将获得一组JSON对象:

>>> json_output
'[{"divroad": "N", "featcat": null, "countyfp": "001",...
Run Code Online (Sandbox Code Playgroud)

或者使用以下内容:

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

你得到一个JSON对象:

>>> j2 = json.dumps(j2)
>>> j2
'{"divroad": "N", "featcat": null, "countyfp": "001",...
Run Code Online (Sandbox Code Playgroud)

  • 优秀的答案!阅读这么多复杂的“转换为对象”类型的答案,这简直令人惊叹。谢谢! (4认同)
  • 这不能很好地支持具有一对多关系的表上的 JOINS。您将获得包含重复数据的行。您需要一个类似于已接受答案的 ORM 来获得可以解决此问题的方法。对于简单的 SQL 到 JSON,这虽然可以正常工作。 (2认同)
  • 我收到错误`datetime.datetime(1941, 10, 31, 0, 0) is not JSON serializable` (2认同)

The*_*emz 22

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
Run Code Online (Sandbox Code Playgroud)

Callin方法没有json ...

print get_all_users()
Run Code Online (Sandbox Code Playgroud)

打印:

[(1, u'orvar', u'password123'), (2, u'kalle', u'password123')]
Run Code Online (Sandbox Code Playgroud)

用json调用方法...

print get_all_users( json_str = True )
Run Code Online (Sandbox Code Playgroud)

打印:

[{"password": "password123", "id": 1, "name": "orvar"}, {"password": "password123", "id": 2, "name": "kalle"}]
Run Code Online (Sandbox Code Playgroud)

  • 最好的答案让我寻找3个月。 (2认同)

det*_*tly 19

就个人而言,我更喜欢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()
Run Code Online (Sandbox Code Playgroud)


g.d*_*d.c 13

有关如何在传输数据之前处理数据的更多信息将有助于实现这一目标.json模块提供了dump(s)和load(s)方法,如果你使用的是2.6或更新版本,它们会有所帮助:http: //docs.python.org/library/json.html.

- 已编辑 -

在不知道您正在使用哪些库的情况下,我无法确定您是否会找到类似的方法.通常,我会像这样处理查询结果(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)
Run Code Online (Sandbox Code Playgroud)

毫无疑问,那里有更好的专家,他们会有列表理解来消除写出循环的需要,但这是有效的,应该是你可以适应你正在检索记录的库.


MrE*_*MrE 7

似乎没有人提供使用 postgres JSON 功能直接从 Postgresql 服务器获取 JSON 的选项 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()
Run Code Online (Sandbox Code Playgroud)

像这样的表:

id, value
----------
1     3
2     7
Run Code Online (Sandbox Code Playgroud)

将返回一个 Python JSON 对象

[{"id": 1, "value": 3},{"id":2, "value": 7}]
Run Code Online (Sandbox Code Playgroud)

然后使用json.dumps转储为 JSON 字符串


Moh*_*med 6

最简单的方法,

使用json.dumps但是如果它的日期时间需要将日期时间解析为 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)
Run Code Online (Sandbox Code Playgroud)

它将返回json 转储

另一种没有 json 转储的简单方法,这里获取标头并使用 zip 进行映射,最终将其制作为 json,但这并不是将日期时间更改为 json 序列化器...

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
Run Code Online (Sandbox Code Playgroud)


hwj*_*wjp 5

我把一个简短的脚本拼凑在一起,根据列名称:值来转储所有表中的所有数据.与其他解决方案不同,它不需要有关表或列的任何信息,它只是查找所有内容并将其转储.希望有人发现它有用!

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))
Run Code Online (Sandbox Code Playgroud)