Pymysql возвращает тот же результат вместо последней строки таблицы через торнадо - PullRequest
0 голосов
/ 30 мая 2018

Мне нужен маленький совет.У меня есть одно проектное приложение, основанное на среде торнадо, где я использую WebSocketHandler.Клиентская сторона отправляет запрос каждые 10 секунд.Часть реализации обработчика WS выглядит следующим образом:

class WebSocketHandler(tornado.websocket.WebSocketHandler):

    def __init__(self, *args, **kwargs):
        self.db_passwrod = kwargs.pop('password')
        self.db_user = kwargs.pop('user')
        self.db_name = kwargs.pop('db_name')
        self.db_connection = db.DbConnection(password=self.db_passwrod,
                                             user=self.db_user,
                                             db_name=self.db_name,
                                             cursor_type=True
                                             )
        super(WebSocketHandler, self).__init__(*args, **kwargs)

    def EnergyDB(self):
        return self.db_connection.fetch_row(table="Energy",
                                            value="ORDER BY Timestamp DESC LIMIT 1",
                                            flag=None)


    def convert(self, object):
        if isinstance(object, datetime.datetime):
            return object.__str__()

    def open(self, *args):
        print("Websocket up")
        self.write_message("coonection established")

    def on_message(self):
        self.write_message(json.dumps(self.EnergyDB))

    def on_close(self):
        print("websocket goes down")

Класс базы данных выглядит следующим образом:

class DbConnection():

    def __init__(self,
                 host='localhost',
                 port=3306,
                 user='user',
                 password='password',
                 db_name=None,
                 cursor_type=None):
                 self.connection = pymysql.connect(host=host,
                                                   user=user,
                                                   passwd=password,
                                                   port=port,
                                                   database=db_name,
                                                   charset='utf8')
        if cursor_type is None:
            self.cursor = self.connection.cursor(pymysql.cursors.SSCursor)
        else:
            self.cursor = self.connection.cursor(pymysql.cursors.SSDictCursor)

    def fetch_row(self, data='*', table=None, vartype=None, value=None, flag=None):
        if flag is not None:
            if value is None:
                self.cursor.execute("SELECT %s FROM %s" %(data, table))
            else:
                self.cursor.execute("SELECT %s FROM %s WHERE %s" %(data, table, value))
        else:
            self.cursor.execute("SELECT %s FROM %s WHERE %s = %s" %(data, table, vartype, value))

         return self.cursor.fetchall()

И я закончил возвращать ту же строку, возможно, собранную при первом вызове ws со стороны клиента,вместо последнего добавленного.Но каждую секунду добавляется новая строка от подключения датчиков машины.Так что, если я правильно понял.Каждый созданный объект курсора pymysql работает с изображением таблицы с момента создания курсора из соображений безопасности / предотвращения повреждения базы данных и игнорирования изменений после создания curosr?И поэтому мне нужно создать новый курсор, собрать значения и удалять curosr каждый запрос?Так как это был первый подход, он работал нормально, но с большой перегрузкой процессора.Или я что-то упустил?

1 Ответ

0 голосов
/ 01 июня 2018
  1. В вашем примере кода вы фактически не вызываете функцию EnergyDB.Я предполагаю, что пропущенные скобки являются просто опечаткой.

  2. Основная проблема здесь заключается в том, что вы повторно используете курсор и транзакцию, поэтому вы видите непротиворечивый снимок базы данных.Вам нужно запускать self.connection.commit() или self.connection.abort() после каждого его использования, чтобы сбросить соединение и увидеть новые данные (если ваши запросы доступны только для чтения, коммит и прерывание эквивалентны).Я не уверен, безопасно ли повторно использовать такой курсор или вам следует каждый раз создавать новый (в своем собственном коде я всегда создаю новый курсор).

  3. Донне используйте оператор % для создания запросов SQL.Это уязвимо для атак с использованием SQL-инъекций.Вместо этого используйте функции подстановки параметров драйвера базы данных, как показано в примере pymysql

...