Peewee 在尝试添加用户定义的运算符时抛出 KeyError

Posted

技术标签:

【中文标题】Peewee 在尝试添加用户定义的运算符时抛出 KeyError【英文标题】:Peewee throws KeyError when trying to add user defined operator 【发布时间】:2015-07-20 09:15:42 【问题描述】:

我按照 peewee 文档中关于如何添加用户定义的运算符的简短指南进行操作,但是当我尝试这样做时,它给了我一个 KeyError。

from peewee import *
from peewee import OP
from peewee import Expression

db = mysqlDatabase(app.config['MYSQL_DATABASE_DB'], host=app.config['MYSQL_DATABASE_HOST'], user=app.config['MYSQL_DATABASE_USER'], passwd=app.config['MYSQL_DATABASE_PASSWORD'])

OP['MOD'] = 'mod'

def mod(lhs, rhs):
    return Expression(lhs, OP.MOD, rhs)

MySQLDatabase.register_ops(OP.MOD: '%')

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

class User(Base):
    user_id = PrimaryKeyField()
    first_name = CharField(max_length = 150)
    last_name = CharField(max_length = 150)

@app.route('/')
def test():
    query = User.select().where(mod(User.user_id, 2) == 0)
    return "Query: %r" % query

当我尝试运行它时,它给了我这个错误:

KeyError: 'mod'

任何想法我可能做错了什么?

【问题讨论】:

【参考方案1】:

在此之前

def mod(lhs, rhs):
    return Expression(lhs, OP.MOD, rhs)

你需要定义这个

OP['MOD'] = 'mod'

【讨论】:

哦,我忘了在我的帖子中包含它,但我已经定义了 OP['MOD'] = 'mod'。编辑了我的帖子。【参考方案2】:

问题是您在调用register_ops() 之前定义了数据库。要修复当前的错误,您可以将您的 db = MySQL... 移动到对 register_ops() 的调用下方。

不过,这确实有点像 peewee 中的错误,所以我打开了一个 github 问题:https://github.com/coleifer/peewee/issues/599


编辑:我决定毕竟不改变行为。不过,我提出的解决方案应该可行——首先注册操作,然后实例化。您还可以在实例化数据库时指定自定义操作:

http://docs.peewee-orm.com/en/latest/peewee/api.html#Database

例子

OP['MOD'] = 'mod'

def mod(lhs, rhs):
    return Expression(lhs, OP.MOD, rhs)

db = MySQLDatabase(
    app.config['MYSQL_DATABASE_DB'], 
    host=app.config['MYSQL_DATABASE_HOST'], 
    user=app.config['MYSQL_DATABASE_USER'], 
    passwd=app.config['MYSQL_DATABASE_PASSWORD'],
    ops=OP.MOD: '%')

【讨论】:

非常感谢!这正是问题所在! 我在尝试使用 psql 数组列类型时遇到 KeyError: 'A@>'。我需要以某种方式为其注册操作吗? 否,但请确保您的数据库是 PostgresqlExtDatabase 而不仅仅是普通的旧 PostgresqlDatabase【参考方案3】:
OP['MOD'] = 'mod'

def mod(lhs, rhs):
    return Expression(lhs, OP.MOD, rhs)

db = MySQLDatabase(
    app.config['MYSQL_DATABASE_DB'], 
    host=app.config['MYSQL_DATABASE_HOST'], 
    user=app.config['MYSQL_DATABASE_USER'], 
    passwd=app.config['MYSQL_DATABASE_PASSWORD'])

指定ops参数会导致错误,其实你不必那样做。

您唯一需要注意的是将您定义的函数mod 导入您要在其中使用它的模块。

【讨论】:

以上是关于Peewee 在尝试添加用户定义的运算符时抛出 KeyError的主要内容,如果未能解决你的问题,请参考以下文章

UI 元素添加到控件集合时抛出异常

Android布局预览器在添加自定义LinearLayout时抛出错误

JPA CONCATE 与 IN 运算符一起使用时抛出异常

Ninja 框架端点在尝试将 JSON 映射到自定义对象时抛出 500 错误

Nuget 包 - 提要 (VSTS):尝试添加源时抛出异常“System.AggregateException”

Windows Azure:“已添加具有相同密钥的项目。”选择时抛出异常