pymysql事务无法与多个函数调用一起正常使用

时间:2019-02-07 09:39:41

标签: python mariadb pymysql

我使用pymysql和pandas插入了大量数据。 最初,我不指望交易和回滚。 但是由于某些原因,我需要处理交易。因此,我建立了既可以用作“自动提交,自动关闭”又可以用作“手动提交,手动关闭”的功能。但是,当像下面的代码的insertData函数那样将其用作手册时,它会成功查询但未提交,因此db表为空。

我希望多次调用查询功能会导致执行的查询结果丢失。所以提交真的什么都不做。

可以检查吗?我在2019年2月7日使用python 3.6,pymysql最新版本,MariaDB最新稳定版本。

下面的代码有些缺陷,因为我在几分钟之内就建立了它们。 但是总体代码流是正确的。我忽略了不必要的代码。 如果您需要更多信息,我将添加它们。谢谢:)

class DBHandler:
    def __init__(host, dbname, ...):
        self.host = host
        self.db = dbname
        # And password, port

    def _get_connection():
        return pymysql.connect(self.host, self.db...)

    def insert(self, query, args, conn=None, commit=True):
        try:
            if args is not None:
                self._set_many(query=query, args=args, conn=conn, commit=commit)
            else:
                self._set(...) # Used with single query (execute curosr.execut()
        except pymysql.Error:
            raise Exception('Query failed')

    def _set_many(self, query, args, conn, commit):
        close = True if conn is None else False
        conn = self._get_connection() if conn is None else conn

        try:
            conn.cursor().executemany(query, args)

        except pymysql.Error as err:
            if close is True:
                conn.close()
            raise pymysql.Error(err)

        if commit is True:  ## Works well when commit=True
            conn.commit()
        if close is True:
            conn.close()

def insertData(db, df):
    conn = db._get_connection() # Will return pymysql.connect(<args>)
    conn.autocommit = False
    conn.begin()

    item_list = []
    query = 'insert into utterance_list (col_1, col_2, col_3) values (col_1=%s, col_2=%s, col_3=%s) where internal_id=%s'

    try:
        for idx in len(df.index):
            item_list.append(<tuplized single row of df which contains `internal_id` col at the last of tuple>)

            if len(item_list) > 100000:
                db.insert(query=query, args=item_list, conn=conn, commit=False)

        if len(item_list) != 0:
            db.insert(query=query, args=item_list, conn=conn, commit=False)

    except Exception as e:
        print('Error on qerying')
        conn.rollback()
        conn.close()

    conn.commit()
    conn.close()

df = get_df_from_somewhere()
db = DBHandler(host='localhost', dbname='mydb', ...)

try:
    insertData(db, df)
except Exception as e:
    print(e)
    exit(1)

print("Query is complete")

# => Query executed successfully without any exception, but table is empty
# => Output
# Query is complete

此外,工作代码在以下哪个版本更早

class DBHandler:
    def __init__(host, dbname, ...):
        self.host = host
        self.db = dbname
        # And password, port

    def _get_connection():
        return pymysql.connect(self.host, self.db...)

    def insert(self, query, args):
        try:
            if args is not None:
                self._set_many(query=query, args=args)
            else:
                self._set(...) # Used with single query (which execute cursor.execute(..))
        except pymysql.Error:
            raise Exception('Error on querying')

    def _set_many(self, query, args):
        conn = self._get_connection()

        try:
            conn.cursor().executemany(query, args)

        except pymysql.Error as err:
            conn.close()
            raise pymysql.Error(err)

        conn.commit()
        conn.close()

def insertData(db, df):
    item_list = []
    query = 'insert into utterance_list (col_1, col_2, col_3) values (col_1=%s, col_2=%s, col_3=%s) where internal_id=%s'

    try:
        for idx in len(df.index):
            item_list.append(<tuplized single row of df which contains `internal_id` col at the last of tuple>)

            if len(item_list) > 100000:
                db.insert(query=query, args=item_list, conn=conn, commit=False)

        if len(item_list) != 0:
            db.insert(query=query, args=item_list, conn=conn, commit=False)

    except Exception as e:
        print('Error on qerying')
        exit(1)

df = get_df_from_somewhere()
db = DBHandler(host='localhost', dbname='mydb', ...)

try:
    insertData(db, df)
except Exception as e:
    print(e)
    exit(1)

print("Query is complete")

# => Query executed successfully without any exception, but table is empty
# => Output
# Query is complete

更新:似乎'commit()'不起作用。我使用服务器连接COMMIT的直接查询成功插入了数据,这意味着事务正在运行,但提交却没有。但是为什么提交不起作用?

1 个答案:

答案 0 :(得分:0)

我更换了服务器计算机,然后再次尝试,它可以找到。似乎是系统规格问题。谢谢您的回答