Вставка JSON в MySQL с использованием Python - PullRequest
14 голосов
/ 23 ноября 2010

У меня есть объект JSON в Python.Я использую Python DB-API и SimpleJson.Я пытаюсь вставить json в таблицу MySQL.

В настоящее время я получаю ошибки, и я считаю, что это связано с одинарными кавычками '' в объектах JSON.

Как я могу вставить мой объект JSON в MySQL, используя Python?

Вот сообщение об ошибке, которое я получаю:

error: uncaptured python exception, closing channel 
<twitstream.twitasync.TwitterStreamPOST connected at 
0x7ff68f91d7e8> (<class '_mysql_exceptions.ProgrammingError'>:
(1064, "You have an error in your SQL syntax; check the 
manual that corresponds to your MySQL server version for 
the right syntax to use near ''favorited': '0', 
'in_reply_to_user_id': '52063869', 'contributors': 
'NULL', 'tr' at line 1") 
[/usr/lib/python2.5/asyncore.py|read|68] 
[/usr/lib/python2.5/asyncore.py|handle_read_event|390] 
[/usr/lib/python2.5/asynchat.py|handle_read|137] 
[/usr/lib/python2.5/site-packages/twitstream-0.1-py2.5.egg/
twitstream/twitasync.py|found_terminator|55] [twitter.py|callback|26] 
[build/bdist.linux-x86_64/egg/MySQLdb/cursors.py|execute|166] 
[build/bdist.linux-x86_64/egg/MySQLdb/connections.py|defaulterrorhandler|35])

Другая ошибка для справки

error: uncaptured python exception, closing channel 
<twitstream.twitasync.TwitterStreamPOST connected at 
0x7feb9d52b7e8> (<class '_mysql_exceptions.ProgrammingError'>:
(1064, "You have an error in your SQL syntax; check the manual 
that corresponds to your MySQL server version for the right 
syntax to use near 'RT @tweetmeme The Best BlackBerry Pearl 
Cell Phone Covers http://bit.ly/9WtwUO''' at line 1") 
[/usr/lib/python2.5/asyncore.py|read|68] 
[/usr/lib/python2.5/asyncore.py|handle_read_event|390] 
[/usr/lib/python2.5/asynchat.py|handle_read|137] 
[/usr/lib/python2.5/site-packages/twitstream-0.1-
py2.5.egg/twitstream/twitasync.py|found_terminator|55] 
[twitter.py|callback|28] [build/bdist.linux-
x86_64/egg/MySQLdb/cursors.py|execute|166] [build/bdist.linux-
x86_64/egg/MySQLdb/connections.py|defaulterrorhandler|35])

Вот ссылка на код, который я использую http://pastebin.com/q5QSfYLa

#!/usr/bin/env python

try:
        import json as simplejson
except ImportError:
        import simplejson

import twitstream
import MySQLdb

USER = ''
PASS = ''

USAGE = """%prog"""


conn = MySQLdb.connect(host = "",
                       user = "",
                       passwd = "",
                       db = "")

# Define a function/callable to be called on every status:
def callback(status):

    twitdb = conn.cursor ()
    twitdb.execute ("INSERT INTO tweets_unprocessed (text, created_at, twitter_id, user_id, user_screen_name, json) VALUES (%s,%s,%s,%s,%s,%s)",(status.get('text'), status.get('created_at'), status.get('id'), status.get('user', {}).get('id'), status.get('user', {}).get('screen_name'), status))

   # print status
     #print "%s:\t%s\n" % (status.get('user', {}).get('screen_name'), status.get('text'))

if __name__ == '__main__':
    # Call a specific API method from the twitstream module:
    # stream = twitstream.spritzer(USER, PASS, callback)

    twitstream.parser.usage = USAGE
    (options, args) = twitstream.parser.parse_args()

    if len(args) < 1:
        args = ['Blackberry']

    stream = twitstream.track(USER, PASS, callback, args, options.debug, engine=options.engine)

    # Loop forever on the streaming call:
    stream.run()

Ответы [ 7 ]

18 голосов
/ 30 ноября 2010

используйте json.dumps (json_value), чтобы преобразовать ваш объект json (объект python) в строку json, которую можно вставить в текстовое поле в mysql

http://docs.python.org/library/json.html

4 голосов
/ 23 ноября 2010

Чтобы расширить другие ответы:

В основном вам необходимо убедиться в двух вещах:

  1. Что у вас есть место для полного объема данных, которые вы хотитевставить в поле, которое вы пытаетесь разместить.Различные типы полей базы данных могут соответствовать разным объемам данных.См .: Типы данных MySQL String .Вам, вероятно, нужны типы "TEXT" или "BLOB".

  2. Чтобы данные были безопасно переданы в базу данных.Некоторые способы передачи данных могут заставить базу данных «смотреть» на данные, и это может привести к путанице, если данные будут выглядеть как SQL.Это также риск для безопасности.См .: SQL-инъекция

Решение для # 1 - проверить, что база данных спроектирована с правильным типом поля.

Решение для #2 - использовать параметризованные (связанные) запросы.Например, вместо:

# Simple, but naive, method.
# Notice that you are passing in 1 large argument to db.execute()
db.execute("INSERT INTO json_col VALUES (" + json_value + ")")

Лучше используйте:

# Correct method. Uses parameter/bind variables.
# Notice that you are passing in 2 arguments to db.execute()
db.execute("INSERT INTO json_col VALUES %s", json_value)

Надеюсь, это поможет.Если так, дайте мне знать.: -)

Если у вас все еще есть проблема, нам нужно более внимательно изучить ваш синтаксис.

1 голос
/ 23 ноября 2010

Вы можете легко вставить intyo текст или столбец BLOB-объектов

db.execute("INSERT INTO json_col VALUES %s", json_value)
0 голосов
/ 11 июля 2019

Самый простой способ вставить карту Python в поле MySQL JSON ...

python_map = { "foo": "bar", [ "baz", "biz" ] }

sql = "INSERT INTO your_table (json_column_name) VALUES (%s)"
cursor.execute( sql, (json.dumps(python_map),) )
0 голосов
/ 08 декабря 2014
@route('/shoes', method='POST')
def createorder():
    cursor = db.cursor()
    data = request.json
    p_id = request.json['product_id']
    p_desc = request.json['product_desc']
    color = request.json['color']
    price = request.json['price']
    p_name = request.json['product_name']
    q = request.json['quantity']
    createDate = datetime.now().isoformat()
    print (createDate)
    response.content_type = 'application/json'
    print(data)
    if not data:
        abort(400, 'No data received')

    sql = "insert into productshoes (product_id, product_desc, color, price, product_name,         quantity, createDate) values ('%s', '%s','%s','%d','%s','%d', '%s')" %(p_id, p_desc, color, price, p_name, q, createDate)
    print (sql)
    try:
    # Execute dml and commit changes
        cursor.execute(sql,data)
        db.commit()
        cursor.close()        
    except:
    # Rollback changes
        db.rollback()
    return dumps(("OK"),default=json_util.default)
0 голосов
/ 30 ноября 2010

Вам нужно взглянуть на фактическую строку SQL, попробуйте что-то вроде этого:

sqlstr = "INSERT INTO tweets_unprocessed (text, created_at, twitter_id, user_id, user_screen_name, json) VALUES (%s,%s,%s,%s,%s,%s)", (status.get('text'), status.get('created_at'), status.get('id'), status.get('user', {}).get('id'), status.get('user', {}).get('screen_name'), status)
print "about to execute(%s)" % sqlstr
twitdb.execute(sqlstr)

Я предполагаю, что вы найдете там несколько случайных кавычек, скобок или скобок.

0 голосов
/ 23 ноября 2010

Ошибка может быть связана с переполнением размера поля, в которое вы пытаетесь вставить свой JSON. Без какого-либо кода вам трудно помочь.

Рассматривали ли вы систему баз данных без SQL, такую ​​как couchdb, которая является базой данных, ориентированной на документы, основанной на формате json?

...