首页 > 解决方案 > 如何将查询绑定到数据库?

问题描述

为什么我的代码(参见posts.py)会导致异常peewee.InterfaceError

peewee.InterfaceError:查询必须绑定到数据库才能调用“执行”。

如何将查询绑定到数据库?

数据库.py

import datetime
from peewee import *

db = SqliteDatabase('database.db')


class BaseModel(Model):
    class Meta:
        database = db

class Image(BaseModel):
    timestamp = DateTimeField(default=datetime.datetime.now)
    image = BlobField()
    age = SmallIntegerField()
    age_unknown = BooleanField()
    nation_unknown = BooleanField()
    armenian = BooleanField()
    bashkir = BooleanField()
    asian = BooleanField()

    quantity_m = BooleanField()
    quantity_m_w = BooleanField()
    quantity_w = BooleanField()

class Template(BaseModel):
    timestamp = DateTimeField(default=datetime.datetime.now)
    content = TextField(unique=True, null=False)
    nation_nomatter = BooleanField()
    age = SmallIntegerField()
    age_nomatter = BooleanField()
    armenian = BooleanField()
    bashkir = BooleanField()
    asian = BooleanField()

    quantity_m = BooleanField()
    quantity_m_w = BooleanField()
    quantity_w = BooleanField()


class Group(BaseModel):
    group_id = IntegerField(unique=True)


class TemplateGroup(BaseModel):
    group = ForeignKeyField(Group)
    post_template = ForeignKeyField(Template)


class ImageGroup(BaseModel):
    image = ForeignKeyField(Image)
    group = ForeignKeyField(Group)


db.connect()


def create_tables(dtb=None):
    tables_names = [Image, Template, Group, TemplateGroup, ImageGroup]
    if dtb:
        dtb.create_tables(tables_names)
    else:
        db.create_tables(tables_names)

帖子.py

import database
from templates import get_not_posted_templates_for_group
...
class PostDesigner:
    ...
    def _get_random_free_image(self, template, **kwargs):
        query = get_not_used_images_for_group(self.group.group_id)
        if not template.nation_nomatter:
            clauses = []
            clauses.append(database.Image.nation_unknown == True)
            if template.armenian:
                clauses.append(database.Image.armenian == True)
            if template.asian:
                clauses.append(database.Image.asian == True)
            if template.bashkir:
            expr = reduce(operator.or_, clauses)
            query = database.Image.select().where(expr)

        query.execute() # Test execute. OK

        if template.quantity_w:
            query = query.select().where(database.Image.quantity_w == True)
        elif template.quantity_m:
            query = query.select().where(database.Image.quantity_m == True)
        elif template.quantity_m_w:
            query = query.select().where(database.Image.quantity_m_w == True)
       
        query.execute() # Test execute. Exception!

        if template.age_nomatter:
            pass
        else:
            amp = FIND_PHOTOS_FOR_TEMPLATE_AGE_AMPLITUDE
            query = query.select().where(
                (database.Image.age.between(template.age - amp, template.age + amp)) | (database.Image.age_unknown == True))

        if 'for_testing' in kwargs and kwargs['for_testing'] is True:
            return query.select()
        else:
            res = query.select().order_by(fn.Random()).get()
            return res
    ...

例外

Traceback (most recent call last):
  File "/home/dzmitry/PycharmProjects/WebCreator/actions.py", line 1403, in <module>
    ActionPrintToGroups(ttables=tables_).execute()
  File "/home/dzmitry/PycharmProjects/WebCreator/actions.py", line 1251, in execute
    post = PostDesigner(group, ttables=self.ttables).get_post()
  File "/home/dzmitry/PycharmProjects/WebCreator/posts.py", line 178, in get_post
    img = PostImage(self._get_random_free_image(template))
  File "/home/dzmitry/PycharmProjects/WebCreator/posts.py", line 223, in _get_random_free_image
    query.execute()
  File "/home/dzmitry/PycharmProjects/WebCreator/venv/lib/python3.6/site-packages/peewee.py", line 1586, in inner
    'to call "%s".' % method.__name__)
peewee.InterfaceError: Query must be bound to a database in order to call "execute".

标签: peewee

解决方案


您一遍又一遍地执行相同的查询,所以是的,这是一个问题。我认为你的意思是添加额外的 WHERE 子句:

    # remove "query = query.select()", just "query = query.where()"
    if template.quantity_w:
        query = query.where(database.Image.quantity_w == True)
    elif template.quantity_m:
        query = query.where(database.Image.quantity_m == True)
    elif template.quantity_m_w:
        query = query.where(database.Image.quantity_m_w == True)

推荐阅读