2010-07-20 36 views

Trả lời

14

Cá nhân tôi thích SQLObject cho loại điều này. Tôi thích một số mã kiểm tra nhanh chóng-và-bẩn tôi phải có được điều này:

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() 
+0

cảm ơn detly. điều này hoạt động tốt, mặc dù tôi nhấn một lỗi có danh sách và dict được đặt tên giống nhau. chỉ cần đổi tên thành dict thành 'bài hát' và tất cả đều hoạt động tốt. –

+0

Vui vì tôi có thể giúp. Lạ lùng là có lỗi - như tôi thấy, họ có (một chút) tên khác nhau - bạn có thể mắc lỗi đánh máy không? – detly

+0

à, tôi hiểu rồi. Có lẽ tôi đã làm. –

13

Thông tin khác về cách bạn sẽ làm việc với dữ liệu của mình trước khi chuyển dữ liệu sẽ giúp một tấn. Mô-đun json cung cấp các phương thức tải (s) và tải (s) sẽ giúp ích nếu bạn đang sử dụng phiên bản 2.6 hoặc mới hơn: http://docs.python.org/library/json.html.

- CHỈNH SỬA -

Nếu không biết bạn đang sử dụng thư viện nào, tôi không thể nói chắc chắn bạn sẽ tìm được phương pháp như thế. Thông thường, tôi sẽ xử lý kết quả truy vấn như thế này (ví dụ với kinterbasdb vì đó là những gì chúng tôi hiện đang làm việc với):

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) 

Có chuyên gia chắc chắn tốt hơn ra có những người sẽ phải comprehensions danh sách để loại bỏ sự cần thiết của viết ra vòng lặp, nhưng điều này hoạt động và phải là một cái gì đó bạn có thể thích ứng với bất kỳ thư viện bạn đang lấy hồ sơ với.

+0

bảng là danh sách các tệp mp3, bao gồm tên bản nhạc, nghệ sĩ và url, sau đó được sử dụng để điền trình phát Âm thanh HTML5. Trình phát tạo danh sách phát qua một đối tượng JSON, vì vậy tôi chỉ đang tìm cách chuyển bảng này sang JSON. Tôi đã nhìn vào các tài liệu, nhưng đã chỉ tự hỏi nếu có một cái gì đó dọc theo dòng của phương pháp ruby ​​'to_json' trong python. –

+0

@ aaron-moodie - Tôi đã cập nhật câu trả lời của mình với mã ví dụ khác. Hy vọng rằng sẽ giúp. –

+0

Cách tiếp cận tốt đẹp nhưng tôi đã phải thực hiện hai thay đổi để làm cho nó hoạt động cho tôi. bài hát phải là từ điển: "songs = {}" và thay vì songs.append (bài hát) tôi đã sử dụng bài hát [song ['Id']] = bài hát. Nếu không json.dumps (bài hát) sẽ dừng lại với một lỗi rằng các bài hát ist không serializable. –

54

Đây là một ví dụ thực sự tốt đẹp của a pythonic way to do that:

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) 

Bạn nhận được một mảng của các đối tượng JSON:

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

Hoặc như sau:

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

bạn nhận được một đối tượng duy nhất JSON:

>>> j2 = json.dumps(j2) 
>>> j2 
'{"divroad": "N", "featcat": null, "countyfp": "001",... 
+1

Câu trả lời tuyệt vời! Đọc các câu trả lời kiểu "convert to object" phức tạp đến nỗi nó chỉ đơn giản là tuyệt đẹp. CẢM TẠ! – andig

+0

tôi hoàn toàn đồng ý với nhận xét ở trên. đây là một giải pháp tuyệt vời. –

+0

Điều này không hỗ trợ JOINS trên các bảng có mối quan hệ một đến nhiều rất tốt. Bạn sẽ nhận được các hàng có dữ liệu lặp lại. Bạn cần một ORM như câu trả lời được chấp nhận để có được một cái gì đó mà sẽ khắc phục vấn đề này. Đối với SQL đơn giản thành JSON, điều này sẽ hoạt động tốt. – Banjocat

17
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 

callin phương pháp không json ...

print get_all_users() 

in:

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

callin phương pháp với json ...

print get_all_users(json_str = True) 

in:

[{"password": "password123", "id": 1, "name": "orvar"}, {"password": "password123", "id": 2, "name": "kalle"}] 
4

Tôi gõ cùng một kịch bản ngắn mà bãi tất cả dữ liệu từ tất cả các bảng, như dicts tên cột: giá trị. Không giống như các giải pháp khác, nó không yêu cầu bất kỳ thông tin về những gì các bảng hoặc cột được, nó chỉ tìm thấy tất cả mọi thứ và bãi nó. Hy vọng ai đó thấy nó hữu ích!

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)) 
2

tôi sẽ bổ sung The Demz câu trả lời với các phiên bản 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

không ai dường như đã được cung cấp tùy chọn để có được những JSON trực tiếp từ máy chủ PostgreSQL, sử dụng khả năng postgres JSON https://www.postgresql.org/docs/9.4/static/functions-json.html

Không phân tích cú pháp, lặp hoặc bất kỳ mức tiêu thụ bộ nhớ nào ở phía trăn, mà bạn thực sự có thể muốn xem xét nếu bạn đang xử lý 100.000 hoặc hàng triệu hàng.

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() 

một bảng như:

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

sẽ trả về một đối tượng Python JSON

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

Sau đó sử dụng json.dumps để đổ như là một chuỗi JSON cách

+0

điều này có thể được thực hiện chỉ bằng các hàm' psycopg2' và PostgreSQL 'JSON' không? – sc28

+0

kết nối psycopg2 và con trỏ sẽ làm tương tự – MrE

+0

Cảm ơn bạn đã làm rõ! Tôi xác nhận rằng nó thực sự hoạt động với psycopg2. Ví dụ, tôi đã sử dụng hàm 'json_agg()' như được mô tả [ở đây] (http://johnatten.com/2015/04/22/use-postgres-json-type-and-aggregate-functions-to-map -quan hệ-dữ liệu-tới-json /) – sc28

0

đơn giản nhất,

sử dụng json.dumps nhưng nếu datetime của nó sẽ yêu cầu phân tích datetime vào json serializer.

đây là của tôi,

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) 

nó sẽ trở lại json đổ phương pháp đơn giản

một hơn mà không json bãi, đây có tiêu đề và sử dụng zip để lập bản đồ với nhau cuối cùng đã làm cho nó như json nhưng điều này không thay đổi datetime thành 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 
Các vấn đề liên quan