peewee.OperationalError: no such table

时间:2022-11-04 12:20:53

peewee.OperationalError: no such table (目录)

问题描述

初始化数据表的时候,依次执行了

  • 建表
  • 查询数据

报错如下

peewee.OperationalError: no such table: tb_user

问题复现

测试环境

$ python --version
Python 3.7.0

$ pip show peewee
Name: peewee
Version: 3.15.3

定义Model

# -*- coding: utf-8 -*-
from peewee import TextField, AutoField, Model
from playhouse.sqliteq import SqliteQueueDatabase

db = SqliteQueueDatabase(database='database.db')


class UserModel(Model):
    id = AutoField()
    name = TextField()

    class Meta:
        database = db

        table_name = 'tb_user'

1、执行建表和插入

执行正常,没有报错

# 建表
db.create_tables([UserModel])

# 插入数据
UserModel.create(id=1, name='Tom')

2、执行建表和查询

  • 第一次执行的时候,都会报错,提示表不存在
  • 第二次之后执行,就不会报错
# 建表
db.create_tables([UserModel])

# 查询数据
row = UserModel.select('id').where(
    UserModel.id, '=', 1
).get_or_none()

print(row)
# peewee.OperationalError: no such table: tb_user

问题分析

文档:

原文:

SqliteQueueDatabase is designed to simplify things by sending all write queries through a single, long-lived connection. The benefit is that you get the appearance of multiple threads writing to the database without conflicts or timeouts. The downside, however, is that you cannot issue write transactions that encompass multiple queries – all writes run in autocommit mode, essentially.

SqliteQueueDatabase 是单线程写入和多线程读取,写的线程和读的线程并不在一起。

所以,写入还没完成就执行了读取操作,触发了表不存在的报错

问题解决

找到了问题所在,那我们等一等写入线程,再执行读操作

import time
time.sleep(0.01)

完整代码

# -*- coding: utf-8 -*-
import time

from peewee import TextField, AutoField, Model
from playhouse.sqliteq import SqliteQueueDatabase

db = SqliteQueueDatabase(database='database.db')


class UserModel(Model):
    id = AutoField()
    name = TextField()

    class Meta:
        database = db

        table_name = 'tb_user'


# 建表
db.create_tables([UserModel])

# 等一等,写入操作完成再读取
time.sleep(0.01)

# 查询数据
row = UserModel.select('id').where(
    UserModel.id, '=', 1
).get_or_none()

print(row)
# None

参考:Q: How to defer SqliteQueueDatabase? #2095