Нужно ли обновить sh объект подключения sqlalchemy, чтобы иметь возможность вставлять данные во вновь созданную таблицу? - PullRequest
0 голосов
/ 25 февраля 2020

Я новичок в sqlalchemy.

Моя функция подключения в _core.py

from sqlalchemy import create_engine
from methodtools import lru_cache


@lru_cache(maxsize=16)
def get_engine(db="homelan"):
    qs = 'mysql+pymysql://user:pwd@localhost/{db}'.format(db=db)
    engine = create_engine(qs)
    connection = engine.connect()
    return engine, connection

в моем коде, если таблица не существует для указанного c хост-машина, которую я создаю. как показано ниже:

server_status.py

class HostStatusManager(object):

    keep_record = 10 # days

    """This class contains methods to manage the status of the host
    registered in database for supervision or monitoring purpose.
    """

    def __init__(self, ip_address):
        super(HostStatusManager, self).__init__()
        self._ip = ip_address
        engine, connection = _core.get_engine()
        self._engine = engine
        self._connection = connection
        self._host_table = None
        self._host_table_name = None
        if not self.host_status_table_exists():
            self._host_table = self._create_table()



    def get_status(self):
        """Gets the latest status of the host whether online or offline.
        """
        columns = self._host_table.columns
        print("Cols: ".format(columns))
        select_field = getattr(columns, "status")
        query = db.select(
                [select_field]
            ).order_by(
                db.desc(
                    getattr(columns, "id")
                    )
                ).limit(1)
        _log.debug(query)
        ResultProxy = self._connection.execute(query)
        ResultSet = ResultProxy.fetchall()
        if ResultSet:
            return ResultSet[0][0]
        _log.warning("No existing status found from {0}.".format(
            self._host_table
            )
        )

    def set_status(self, data):
        query = db.insert(self._host_table).values(**data)
        results = self._connection.execute(query)

Если я напрямую позвоню set_status, он работает нормально, но get_status выдает ошибку, говоря:

py mysql .err.InternalError: (1412, «Определение таблицы изменилось, повторите попытку транзакции»)

1 Ответ

0 голосов
/ 25 февраля 2020

Вы не должны использовать кэш lru для хранения соединений, а использовать встроенный пул соединений двигателя. Затем каждый раз, когда вам нужно поговорить с базой данных, запросить соединение с движком и закрыть соединение, когда вы закончите с ним. Движок по умолчанию будет иметь пул размером 5.

from sqlalchemy import create_engine

def get_engine(db="homelan"):
    qs = 'mysql+pymysql://user:pwd@localhost/{db}'.format(db=db)
    engine = create_engine(qs)
    return engine

class HostStatusManager(object):

    keep_record = 10 # days

    """This class contains methods to manage the status of the host
    registered in database for supervision or monitoring purpose.
    """

    def __init__(self, ip_address):
        super(HostStatusManager, self).__init__()
        self._ip = ip_address
        engine, connection = _core.get_engine()
        self._engine = engine
        self._host_table = None
        self._host_table_name = None
        if not self.host_status_table_exists():
            self._host_table = self._create_table()



    def get_status(self):
        """Gets the latest status of the host whether online or offline.
        """
        columns = self._host_table.columns
        print("Cols: ".format(columns))
        select_field = getattr(columns, "status")
        query = db.select(
                [select_field]
            ).order_by(
                db.desc(
                    getattr(columns, "id")
                    )
                ).limit(1)
        _log.debug(query)
        connection = self._engine.connect()
        try:
            ResultProxy = connection.execute(query)
            ResultSet = ResultProxy.fetchall()
            if ResultSet:
                return ResultSet[0][0]
            _log.warning("No existing status found from {0}.".format(
                self._host_table
                )
            )
        finally:
            connection.close()

    def set_status(self, data):
        query = db.insert(self._host_table).values(**data)
        connection = self._engine.connect()
        try:
            results = connection.execute(query)
        finally:
            connection.close()

...