【问题标题】:Inserting JSON into MySQL using Python使用 Python 将 JSON 插入 MySQL
【发布时间】:2011-05-14 03:52:20
【问题描述】:

我在 Python 中有一个 JSON 对象。我正在使用 Python DB-API 和 SimpleJson。我正在尝试将 json 插入 MySQL 表中。

目前出现错误,我相信这是由于 JSON 对象中的单引号 ''。

如何使用 Python 将我的 JSON 对象插入 MySQL?

这是我收到的错误消息:

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

【问题讨论】:

  • 一份错误信息的副本会很有帮助:)
  • 您使用什么代码将 JSON 数据实际插入数据库?
  • 希望是个愚蠢的问题,但是您(希望)使用绑定变量吗?
  • @Gerrat 对不起,我是 Python 的新手,不确定我是否知道绑定变量是什么 :-( 抱歉...将代码放到网上以显示脚本。
  • @Will McCutchen 我已经用 pastebin 链接添加了我的代码副本...

标签: python mysql json python-db-api


【解决方案1】:

例如,如何使用PythonJSON 文件添加到MySQL。这意味着需要将JSON文件转换为sql insert,如果有多个JSON对象,那么最好只调用一次INSERT而不是多次调用,即每个对象调用函数INSERT INTO.

# import Python's JSON lib
import json

# use JSON loads to create a list of records
test_json = json.loads('''
[
    {
    "COL_ID": "id1",
    "COL_INT_VAULE": 7,
    "COL_BOOL_VALUE": true,
    "COL_FLOAT_VALUE": 3.14159,
    "COL_STRING_VAULE": "stackoverflow answer"
    },
    {
    "COL_ID": "id2",
    "COL_INT_VAULE": 10,
    "COL_BOOL_VALUE": false,
    "COL_FLOAT_VALUE": 2.71828,
    "COL_STRING_VAULE": "http://stackoverflow.com/"
    },
    {
    "COL_ID": "id3",
    "COL_INT_VAULE": 2020,
    "COL_BOOL_VALUE": true,
    "COL_FLOAT_VALUE": 1.41421,
    "COL_STRING_VAULE": "GIRL: Do you drink? PROGRAMMER: No. GIRL: Have Girlfriend? PROGRAMMER: No. GIRL: Then how do you enjoy life? PROGRAMMER: I am Programmer"
    }
]
''')

# create a nested list of the records' values
values = [list(x.values()) for x in test_json]
# print(values)

# get the column names
columns = [list(x.keys()) for x in test_json][0]

# value string for the SQL string
values_str = ""

# enumerate over the records' values
for i, record in enumerate(values):

    # declare empty list for values
    val_list = []
   
    # append each value to a new list of values
    for v, val in enumerate(record):
        if type(val) == str:
            val = "'{}'".format(val.replace("'", "''"))
        val_list += [ str(val) ]

    # put parenthesis around each record string
    values_str += "(" + ', '.join( val_list ) + "),\n"

# remove the last comma and end SQL with a semicolon
values_str = values_str[:-2] + ";"

# concatenate the SQL string
table_name = "json_data"
sql_string = "INSERT INTO %s (%s)\nVALUES\n%s" % (
    table_name,
    ', '.join(columns),
    values_str
)

print("\nSQL string:\n\n")
print(sql_string)

输出:


SQL string:


INSERT INTO json_data (COL_ID, COL_INT_VAULE, COL_BOOL_VALUE, COL_FLOAT_VALUE, COL_STRING_VAULE)
VALUES
('id1', 7, True, 3.14159, 'stackoverflow answer'),
('id2', 10, False, 2.71828, 'http://stackoverflow.com/'),
('id3', 2020, True, 1.41421, 'GIRL: Do you drink? PROGRAMMER: No. GIRL: Have Girlfriend? PROGRAMMER: No. GIRL: Then how do you enjoy life? PROGRAMMER: I am Programmer.');

【讨论】:

    【解决方案2】:

    这里有一个快速提示,如果你想编写一些内联代码,比如一个小的 json 值,没有import json。 您可以通过双引号对 SQL 中的引号进行转义,即使用''"" 输入'"

    示例 Python 代码(未测试):

    q = 'INSERT INTO `table`(`db_col`) VALUES ("{k:""some data"";}")'
    db_connector.execute(q)
    

    【讨论】:

      【解决方案3】:

      将 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),) )
      

      【讨论】:

      • 非常感谢这在通过自定义命令行界面更新行时非常有用,方法是使用 json.dumps 包装嵌套的 json 对象
      【解决方案4】:
      @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)
      

      【讨论】:

        【解决方案5】:

        使用 json.dumps(json_value) 将您的 json 对象(python 对象)转换为 json 字符串,您可以将其插入 mysql 的文本字段中

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

        【讨论】:

        • 当列的数据类型为text 时,str(json.dumps(json_value)) 为我工作。没有str() 没有错误,但该列是空的
        【解决方案6】:

        你需要看看实际的 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)
        

        我想你会在其中找到一些杂散的引号、方括号或圆括号。

        【讨论】:

        • 好的,如果我有杂散的引号、方括号或圆括号 - 我如何准备用于 SQL 的字符串 Python DB-API 中是否有函数?
        • 对于 SQL 语法中的错误,“准备与 SQL 一起使用的字符串”意味着修复语法......可能不是 API 调用 :) 将输出从“即将到执行...”语句。
        【解决方案7】:

        扩展其他答案:

        基本上你需要确保两件事:

        1. 您有空间容纳要插入到您尝试放置的字段中的全部数据量。不同的数据库字段类型可以适应不同数量的数据。 请参阅:MySQL String Datatypes。您可能需要“TEXT”或“BLOB”类型。

        2. 您正在安全地将数据传递到数据库。某些传递数据的方式可能会导致数据库“查看”数据,如果数据看起来像 SQL,它会感到困惑。这也是一个安全风险。见:SQL Injection

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

        希望这会有所帮助。如果是这样,请告诉我。 :-)

        如果您仍有问题,那么我们将需要更仔细地检查您的语法。

        【讨论】:

        • @Aran 我的回答有帮助吗?如果是这样投票并标记回答..谢谢。 :)
        • 我刚刚上传了我的代码,但在尝试各种方法编写 SQL 查询时似乎仍然出现错误...
        【解决方案8】:

        您应该能够轻松地插入文本或 blob 列

        db.execute("INSERT INTO json_col VALUES %s", json_value)
        

        【讨论】:

          【解决方案9】:

          错误可能是由于您尝试在其中插入 json 的字段的大小溢出。没有任何代码,很难帮你。

          你有没有考虑过像couchdb这样的no-sql数据库系统,它是一个依赖于json格式的面向文档的数据库?

          【讨论】:

          • OP 显示的两个错误都包含:“您的 SQL 语法有错误;...”。这与字段大小溢出无关。
          猜你喜欢
          • 2018-03-02
          • 2019-01-08
          • 2014-08-16
          • 2016-01-17
          • 2015-06-05
          • 2014-02-26
          • 2016-10-10
          • 2017-12-31
          • 2018-05-31
          相关资源
          最近更新 更多