У меня есть этот код на питоне, он читает данные, поступающие из последовательного порта; Данные отправляются с одного XBee и принимаются другим XBee, второй XBee подключается к компьютерному порту, и данные, которые он получает, это то, что я читаю, затем я пытаюсь отправить эти данные в базу данных mysql, но я отправляю следующее ошибка:
«MySQLdb._exceptions.ProgrammingError: %b требуется байтовый объект или объект, который реализует байты, а не 'dict'»
КОД:
import serial
from xbee import XBee
import MySQLdb
serial_port = serial.Serial('COM5', 9600)
xbee = XBee(serial_port)
while True:
try:
value = xbee.wait_read_frame()
sql_conn = MySQLdb.connect('localhost', 'root', 'pass', 'XBee')
cursor = sql_conn.cursor()
cursor.execute("INSERT INTO xbeedata (value) VALUES (%s)", (value))
data = cursor.fetchall()
cursor.close()
print (xbee.wait_read_frame())
except KeyboardInterrupt:
break
serial_port.close()
С уважением.
Есть некоторые проблемы с вашим кодом:
Вам не нужно каждый раз в цикле подключаться к базе данных MySQL.
Согласно документы:
Information returned from this library is a dictionary in the following format:
{'id':str, 'param':binary data, ...}
The id field is always a human-readable name of the packet type received. All following fields, shown above with the key ‘param’, map binary data to each of the possible fields contained within the received data frame.
Таким образом, value
— это тип словаря, и вам нужно использовать ключ param
, который является вашими действительными данными. Я не уверен, что такое param
в вашем примере, но вы можете просто поставить print(value)
и посмотреть результаты. Если вы все еще настаиваете на добавлении value
в свою таблицу, вам нужно сериализовать ее как строку JSON.
import serial
from xbee import XBee
import MySQLdb
import json
from pprint import pprint
serial_port = serial.Serial('COM5', 9600)
xbee = XBee(serial_port)
sql_conn = MySQLdb.connect('localhost', 'root', 'pass', 'XBee')
cursor = sql_conn.cursor()
while True:
try:
value = xbee.wait_read_frame()
if value:
pprint(value)
# Assumed results in 'rf_data' ('param') key
# the 'rf_data' is byte string so it is better to decode it first
cursor.execute(
"""INSERT INTO xbeedata (value) VALUES ('%s')""" % (value['rf_data'].decode()))
# or if you want to insert whole value
# cursor.execute(
# """INSERT INTO xbeedata (value) VALUES ('%s')""" % (json.dumps(value)))
sql_conn.commit()
except KeyboardInterrupt:
break
sql_conn.close()
serial_port.close()
Еще нет. С уважением.
Можете ли вы добавить полную трассировку к вашему вопросу? Я имею в виду все ошибки.
Да, конечно, это ошибка: " {'id': 'rx', 'options': b'\x01', 'rf_data': b' ArduinoA_BtnA = 1 ', 'source_addr': b'\xf3\n', 'source_addr_long': b'\ x00\x13\xa2\x00A\x97\xeaT'} Трассировка (последний последний вызов): Файл "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\MySQLdb\ cursors.py", строка 201, в запросе выполнения = запрос % args TypeError: не все аргументы преобразованы во время форматирования байтов "
Теперь я получаю эту ошибку: "Теперь я получаю эту ошибку: {'id': 'rx', 'options': b'\x01', 'rf_data': b' ArduinoA_BtnA = 1', 'source_addr': b'\xf3\n', ' source_addr_long': b'\x00\x13\xa2\x00A\x97\xeaT'} Трассировка (последний последний вызов): Файл "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\si te-packages\MySQLdb\cursors.py", строка 201, в запросе выполнения = запрос % args TypeError: не все аргументы преобразованы во время форматирования байтов " .....
Я удалил форматирование из вашего запроса, проверьте новый, теперь он должен работать. Я также исправил кортеж для добавления одного элемента.
Что такое таблица xbeedata
, сколько в ней столбцов? Я не уверен насчет типа value
, который вы пытаетесь вставить. Это капля? Можете ли вы опубликовать запрос SQL для таблицы?
Таблица xbee имеет 2 столбца, идентификатор и значение, значение имеет тип varchar. Это структура таблицы: drive.google.com/file/d/1o13NDU-_VEP0xQm1aT2SRcRynJ1cjT8g/…
Хорошо, значение представляет собой строку, а value['rf_data']
— строку байтов. попробуй это cursor.execute("""INSERT INTO xbeedata (value) VALUES ('%s')""" % (value['rf_data'].decode()))
Я отредактировал код, но лучше использовать cursor.execute("INSERT INTO xbeedata (value) VALUES (%s)", (value['rf_data'].decode(),))
, так как используется paramtererize sql.
Спасибо, М. Р. С уважением.
Другой вопрос, значение, которое я получаю, таково: «ArduinoA_BtnA=1». Есть ли способ разделить строку и поместить «1» в другой столбец?
Почему бы и нет, вы можете использовать result = 'ArduinoA_BtnA=1'.split(" = ")
, тогда result[0]
— строка, а result[1]
— число.
Здравствуйте, спасибо за ответ, это строка, которую я получаю: "{'id': 'rx', 'source_addr_long': b'\x00\x13\xa2\x00A\x97\xeaT', 'source_addr': b'\xf3\n', 'options': b'\x01 ', 'rf_data': b 'ArduinoA_BtnA = 1'} " Данные, которые мне нужны, находятся в «rf_data», поэтому я меняю «param» на «rf_data», когда я запускаю код, я получаю эту ошибку: «TypeError: не все аргументы преобразуются при форматировании байтов". С уважением