Найти - Пользователи
Полная версия: Асинхронные запросы для одной таблицы.
Начало » Базы данных » Асинхронные запросы для одной таблицы.
1
Red_Dragon
Есть небольшой скрип работы с БД:
import json
import collections
import pymysql
cnx = pymysql.connect(user='root', passwd='***',
                      host='127.0.0.1',
                      db='***')
def update_stats(user, link):
    if link == True:
        stats_template = (
            "INSERT INTO stats (user) VALUES(%(userPar)s) ON DUPLICATE KEY UPDATE  messages=messages+1, links=links+1")
    else:
        stats_template = (
            "INSERT INTO stats (user) VALUES(%(userPar)s) ON DUPLICATE KEY UPDATE messages=messages+1")
    stats_data = {
        'userPar': user,
    }
    try:
        cursor_insert = cnx.cursor()
        cursor_insert.execute(stats_template, stats_data)
    except pymysql.Error as e:
        print("Error %d: %s" % (e.args[0], e.args[1]))
    finally:
        cursor_insert.close()
def get_all():
    try:
        cursor_get = cnx.cursor()
        cursor_get.execute("SELECT * FROM stats")
        rows = cursor_get.fetchall()
    except pymysql.Error as e:
        print("Error %d: %s" % (e.args[0], e.args[1]))
    finally:
        cursor_get.close()
    objects_list = []
    for row in rows:
        d = collections.OrderedDict()
        d['user'] = row[0]
        d['messages'] = row[1]
        d['links'] = row[2]
        objects_list.append(d)
    return json.dumps(objects_list)

update_stats и get_all вызываются из разных потоков, то есть могут быть вызваны и одновременно. Ожидал, что если таблица заблокирована одним запросом, то другой будет просто ожидать, но что-то пошло не так. Иногда получаю такое:
File "C:\PythonTools\Python34\lib\site-packages\websocket\_app.py", line 211, in _callback
    callback(self, *args)
  File "C:/Users/user/PycharmProjects/untitled/WS.py", line 9, in on_message
    analysis.string_to_json(message)
  File "C:\Users\user\PycharmProjects\untitled\analysis.py", line 15, in string_to_json
    db_operations.update_stats(user, linksBool)
  File "C:\Users\user\PycharmProjects\untitled\db_operations.py", line 25, in update_stats
    cursor_insert.execute(stats_template, stats_data)
  File "C:\PythonTools\Python34\lib\site-packages\pymysql\cursors.py", line 135, in execute
    result = self._query(query)
  File "C:\PythonTools\Python34\lib\site-packages\pymysql\cursors.py", line 274, in _query
    conn.query(q)
  File "C:\PythonTools\Python34\lib\site-packages\pymysql\connections.py", line 714, in query
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "C:\PythonTools\Python34\lib\site-packages\pymysql\connections.py", line 865, in _read_query_result
    result.read()
  File "C:\PythonTools\Python34\lib\site-packages\pymysql\connections.py", line 1068, in read
    self._read_result_packet(first_packet)
  File "C:\PythonTools\Python34\lib\site-packages\pymysql\connections.py", line 1108, in _read_result_packet
    self._get_descriptions()
  File "C:\PythonTools\Python34\lib\site-packages\pymysql\connections.py", line 1181, in _get_descriptions
    field = self.connection._read_packet(FieldDescriptorPacket)
  File "C:\PythonTools\Python34\lib\site-packages\pymysql\connections.py", line 829, in _read_packet
    packet = packet_type(buff, self.encoding)
  File "C:\PythonTools\Python34\lib\site-packages\pymysql\connections.py", line 363, in __init__
    self.__parse_field_descriptor(encoding)
  File "C:\PythonTools\Python34\lib\site-packages\pymysql\connections.py", line 373, in __parse_field_descriptor
    self.org_table = self.read_length_coded_string().decode(encoding)
  File "C:\PythonTools\Python34\lib\site-packages\pymysql\connections.py", line 321, in read_length_coded_string
    length = self.read_length_encoded_integer()
  File "C:\PythonTools\Python34\lib\site-packages\pymysql\connections.py", line 302, in read_length_encoded_integer
    c = ord(self.read(1))
  File "C:\PythonTools\Python34\lib\site-packages\pymysql\connections.py", line 258, in read
    raise AssertionError(error)
Error 2014: Command Out of Sync

Похоже, если таблица заблокирована одним запросом, то другой просто выдает ошибку.
Пробовал офф драйвер для MySql, сейчас перешел на pymysql, результат тот-же.
Питон не мой основной язык на котором я пишу, так что решая эту проблему могу пойти по ложному пути. Посоветуйте как решить эту проблему правильно?
4kpt_III
Red_Dragon
Питон не мой основной язык на котором я пишу, так что решая эту проблему могу пойти по ложному пути.

Писать на основном языке

Ну а если серьезно - ОРМ.
Red_Dragon
4kpt_III
Ну а если серьезно - ОРМ.
А другой путь? Не хочется использовать ORM ради пары простых запросов.
4kpt_III
Да ну какая разница. Используйте его просто для подключения к БД. С алхимией можно работать тремя путями. Один из которых предполагает использовать ее просто как коннектор к БД.
PooH
Вы упомянули про потоки, я подозреваю что вы используете одно соединение для всех потоков и проблема не в базе, а в том что один поток пытается выполнить команду, пока другой еще не очистил буфер(я не смотрел внутренности pymysql, чисто интуитивно). Может попробовать создать пул соединений и потокам брать оттуда свободные и возвращать после обработки?

ЗЫ: для быстрой проверки предположения, просто попробуйте создавать в каждом потоке новое подключение, если заработает переходите на пул
terabayt
txMySQL
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB