【问题标题】:Proper peewee setup for avoiding mysql sync issues when using Python3 multiprocessing?使用 Python3 多处理时避免 mysql 同步问题的正确 peewee 设置?
【发布时间】:2019-12-19 05:52:10
【问题描述】:

今天,我接手了一个朋友的项目,让我大吃一惊。当尝试写入远程 MySQL 数据库时,它吐出这个错误:

peewee.OperationalError: (2014, 'Command Out of Sync')

仔细观察,程序仅在初始化阶段运行 connect() 到数据库,并且仅在程序退出时运行 close()。然而,这是一个多处理 Python 应用程序,它通常一次执行大约 4 个进程,每个进程读取和写入我们的数据库。

根据我之前使用 MySQL 的经验,以及对这个特定错误的研究,这似乎是在两条语句同时执行时发生的。因此,需要对方法进行一些重写。

大多数方法都包含在与数据库交互的类中,例如:

Class Foo

...

def register_foo(self) -> Foo:

                saved = False
                attempts = 0


                while not saved:

                        if attempts >= 20:

                                print('error: could not register foo!')
                                return None

                        try:
                                foo, created = Foo.get_or_create()

                        except Exception as e:

                                print(e)
                                sleep(2.5)
                                attempts += 1

                                continue

                        saved = True

                return foo

这似乎根本不对。我想它有时可以解决这个问题,但我更愿意通过同步到数据库来解决这个问题。

我的问题是分割 Python3 脚本的 peewee 方法以便在写入远程数据库时不会出现同步问题的正确方法是什么?

【问题讨论】:

标签: python mysql peewee pymysql


【解决方案1】:

仔细观察,程序仅在初始化阶段运行 connect() 到数据库,并且仅在程序退出时运行 close()。然而,这是一个多处理 Python 应用程序,它通常一次执行大约 4 个进程,每个进程读取和写入我们的数据库。

您需要做的是 fork 新进程之后连接到数据库。这样,当新进程启动时,内部状态(文件描述符等)是干净的。

【讨论】:

    【解决方案2】:

    适用于在遥远的未来发现这一点的任何人。如果您在使用 peewee 和 MySQL 时遇到 2006 或 2014 错误,请使用以下 mixin 类:

    from playhouse.shortcuts import ReconnectMixin
    
    class ReconnectMySQLDatabase(ReconnectMixin, MySQLDatabase):
            pass
    

    并使用 ReconnectMySQLDatabase 而不是 MySQLDatabase 进行 peewee 交互。

    【讨论】:

    • 这是一个糟糕的答案,因为它没有解决实际问题,只是通过吞下错误来掩盖它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-04
    • 1970-01-01
    • 2013-07-10
    相关资源
    最近更新 更多