現時点で最新の mysql-connector-python 8.0.33 のバージョンで

  • コネクションを複数作る
  • 複数の接続からcur.fetchone() と yield でストリームを作る

というコードを書くと

Fatal Python error: deallocating None

というエラーが出てしまいます。

バージョン 8.0.18 以下にすると問題なく動くのでこのような実装をしている人はアップデートに気をつけましょう。

アップデートで解消されるようなことがあったら追記します。

サンプルコード
TABLE_Aをyieldしながらもう一つコネクションをつないでTABLE_Aに紐づくTABLE_Bを取得するサンプルコードです。

import mysql.connector


class MainClass:
    def run(self):
        generator = DebugGenerator()
        stream = generator.debug_stream()
        for datum in stream:
            print(datum)


class DebugGenerator:
    def get_table_a(self):
        db = DB.connect()
        cur = db.cursor(dictionary=True, buffered=False)
        query = """
            SELECT *
            FROM `TABLE_A`
        """
        cur.execute(query)
        row = cur.fetchone()
        table_a_id = row["id"]
        # ---問題の箇所---
        # TABLE_Aを取得しながらidで紐付いているTABLE_Bを取得する
        #
        while row is not None:
            for d in self.get_table_b(table_a_id):
                yield d
            yield row
            row = cur.fetchone()

    def get_table_b(self, id):
        db = DB.connect()
        cur = db.cursor(dictionary=True, buffered=False)
        query = """
            SELECT *
            FROM `TABLE_B`
            WHERE table_a_id = %s
        """
        cur.execute(
            query, [id]
        )
        row = cur.fetchone()
        while row is not None:
            yield row
            row = cur.fetchone()
        cur.close()


class DB:
    DB_USER = "hoge"
    DB_PASS = "hoge"
    DB_HOST = "hoge"
    DB_PORT = "hoge"
    DB_DATABASE = "hoge"

    def connect(self):
        return mysql.connector.connect(
            user=self.DB_USER,
            password=self.DB_PASS,
            host=self.DB_HOST,
            port=self.DB_PORT,
            database=self.DB_DATABASE
        )


if __name__ == '__main__':
    main_class = MainClass()
    main_class.run()