Django默认隔离级别和数据库二进制日志格式错误

时间:2018-07-17 15:11:40

标签: python mysql django mariadb

我正在django的{​​{1}}网络服务器上运行一组测试。我正在尝试在travis上的测试/ CI中从MySQL数据库服务器切换至MariaDB,为此,我也从pytest-django python软件包切换至mysqldb

在使用MariaDB时,我突然发现与数据库相关的测试 all 出现了一个奇怪的异常:

  

pymysql.err.InternalError:(1665,'无法执行语句:由于BINLOG_FORMAT = STATEMENT,并且至少一个表使用了仅限于基于行的日志记录的存储引擎,因此无法写入二进制日志。InnoDB仅限于行记录日志当事务隔离级别为READ COMMITTED或READ UNCOMMITTED。')

该异常在该工作的所有测试中的几个异常堆栈中下方,但是我已将其确定为问题的根本原因。

重要的是要注意,在直接在travis上运行测试套件的两个作业和在docker上(在travis内)运行它的另一个作业中,只有一个失败,一个在python 3.6上运行。

尽管我大致了解问题的原因,但我找不到大量有关具体信息或突然触发/表明其原因的信息。除了此Django documentation issue

鉴于它仅是针对python3测试工作而触发的,而Django2放弃了对python2的支持,我认为这些问题是相关的,但我似乎仍然找不到一个合理/合理的解决方案。我觉得我至少缺少这里所发生情况的某些原因/原因。

我没有对数据库配置进行任何更改,所有服务都通过内置安装运行。

作为参考,this是PR的Travis工作,以防万一我错过了重要的事情。

2 个答案:

答案 0 :(得分:0)

TL; DR:安装了更新的MariaDB版本即可解决此问题。

通过阅读有关该问题的更多信息,我能够确定根本原因确实是由于环境中两个 default 配置之间的冲突所致:

  1. BINLOG_FORMAT = STATEMENT

    根据MariaDB's documentation,这是MariaDB的默认版本,直到版本10.2.4。由于我使用的是Travis-CI,并且由于using MariaDB on travisCI was documented版本10.0是 hardcoded 的,因此默认为以上值。

  2. 事务隔离级别设置为READ COMMITTED

    在Python3上,安装了Django> = 2.0,其中根据Django's documentation将事务隔离级别设置为READ COMMITTED。此配置似乎是一个更安全的默认值。

在示例travis mariadb代码段中替换主要/次要版本字符串:

addons:
  - mariadb: '10.0'

使用'10.3'的仅主要版本字符串使travis安装了最新版本或MariaDB,默认版本为更灵活的BINLOG_FORMAT = MIXED配置。

答案 1 :(得分:0)

# config as this way, add options
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'xxx',
        'USER': 'xx',
        'PASSWORD': 'xx',
        'HOST': 'xxx',
        'POST': 'xxx',
        'OPTIONS': {
            'isolation_level': "repeatable read"
        },
    },
}