Inserindo JSON no MySQL usando Python
-
27-09-2019 - |
Pergunta
Eu tenho um objeto JSON em Python. Estou usando Python DB-API e Simplejson. Estou tentando inserir o JSON em uma tabela MySQL.
No momento, estou recebendo erros e acredito que é devido às citações únicas '' nos objetos JSON.
Como posso inserir meu objeto JSON no MySQL usando o Python?
Aqui está a mensagem de erro que recebo:
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])
Outro erro para referência
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])
Aqui está um link para o código que estou usando 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()
Solução
Use json.dumps (json_value) para converter seu objeto JSON (objeto Python) em uma string json que você pode inserir em um campo de texto em Mysql
Outras dicas
Para expandir as outras respostas:
Basicamente, você precisa ter certeza de duas coisas:
Que você tem espaço para a quantidade total de dados que deseja inserir no campo que está tentando colocá -los. Diferentes tipos de campo de banco de dados podem se ajustar a diferentes quantidades de dados. Ver: Mysql string datatypes. Você provavelmente deseja os tipos de "texto" ou "blob".
Que você está passando com segurança os dados para o banco de dados. Algumas maneiras de passar dados podem fazer com que o banco de dados "observe" os dados e ficará confuso se os dados se parecer com o SQL. É também um risco de segurança. Ver: Injeção SQL
A solução para o número 1 é verificar se o banco de dados foi projetado com o tipo de campo correto.
A solução para o #2 é use consultas parametrizadas (ligadas). Por exemplo, em vez de:
# 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 + ")")
Melhor, use:
# 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)
Espero que isto ajude. Se sim, me avise. :-)
Se você ainda estiver tendo um problema, precisaremos examinar sua sintaxe mais de perto.
Você deve ser capaz de inserir uma coluna Intyo um texto ou blob facilmente
db.execute("INSERT INTO json_col VALUES %s", json_value)
A maneira mais direta de inserir um mapa python em um campo 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),) )
O erro pode ser devido a um estouro do tamanho do campo em que você tenta inserir seu JSON. Sem nenhum código, é difícil ajudá -lo.
Você já atendeu a um sistema de banco de dados NO-SQL, como o CouchDB, que é um banco de dados orientado a documentos que confia no formato JSON?
Você precisa dar uma olhada na string SQL real, tente algo assim:
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)
Eu imagino que você encontrará algumas citações, suportes ou parênteses perdidos lá.
@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)
Aqui está uma dica rápida, se você quiser escrever algum código em linha, digamos para um pequeno valor JSON, sem import json
. Você pode escapar das citações no SQL por uma citação dupla, ou seja, use ''
ou ""
, entrar '
ou "
.
Amostra de código python (não testado):
q = 'INSERT INTO `table`(`db_col`) VALUES ("{k:""some data"";}")'
db_connector.execute(q)