peewee: SQLite - peewee Create() 在主键字段为数字开头时强制使用整数(即使中间有非数字字符)

0 投票
1 回答
23 浏览
提问于 2025-04-12 03:09

这是我的代码。我的目标是将一条记录插入到一个表中,并使用两个用下划线连接的数字作为主键。最终,这个主键会由一个物品编号和一个检查时间(用下划线分隔)组成,但为了简单起见,下面的示例代码我做了简化。

from peewee import *

db = SqliteDatabase('itemstocheck.sqlite')

class PriceCheck(Model):
    pricecheck_id = PrimaryKeyField()
    item_number = TextField()
    price = DecimalField()
    bids_qty = IntegerField()
    datetime_checked = TextField()
    
    class Meta:
            database = db
            db_table = "pricechecks"

def main():

    print("***** Let's create a price check entry in the DB *****")
    PriceCheck.create(
        pricecheck_id = "47_3_1", # the underscores are getting stripped out and the "string" is treated as an integer by peewee, if you preface the leading numeric with a non-numeric, peewee treats it as string
        item_number = "123456789",
        price="70.91",
        bids_qty="4",
        datetime_checked="987654321"
        )

if __name__ == "__main__":
    main()

问题:

你会看到第20行的 pricecheck = "47_3_1"。Peewee(一个Python库)把这个下划线去掉了,结果把整数 4731 发送到了数据库字段里。如果你把它改成 pricecheck = "47_3__1" 或者 "47__3_1",Peewee就不会去掉下划线了。你可以随意插入多个单个下划线,它们都会被去掉。如果有多个连续的下划线,整个内容就会被当作字符串处理。如果有前导或后缀的下划线,它也会被当作字符串处理。

编辑:这确实被当作整数处理(或者可能是小数)。我尝试在下划线后面加一个小数点(比如 772_1.2),下划线被去掉了,但小数点保留了。我还测试了前导零是保留还是去掉。当有一个单一的下划线时(比如 077_1077_1.2),前导零会被去掉,下划线也会被去掉。这告诉我它是把这个值当作小数或整数处理的。但是如果有两个下划线(比如 077__1),前导零就不会被去掉。

这种情况发生在你把字段当作 PrimaryKeyField 在模型中处理时。如果你把它当作普通的 TextField,就不会出现这种情况(换句话说,即使在几个数字之间有一个单一的下划线,它也会保留)。

一个解决办法是不用太担心,因为SQLite会按照你在模式中定义的方式存储值。另一个办法是给数字前面加一个字母(比如 "a_47_3_1")。还有一个办法是故意使用双下划线。但这些解决办法都感觉像是临时的补救措施。

但对我来说更大的问题是,这种行为意味着我无法在主键中存储我需要的值。而且我只能存储不超过 9223372036854775807(有符号的64位整数)。

这种行为是正确的吗?我只是没有意识到吗?

在主键字段中,下划线算不算某种分隔符?

为什么在 PrimaryKeyField 上会这样,而在 TextField 上却不会?我认为 PrimaryKeyField(在peewee ORM中)并不在乎内容是什么,只要输入的值是唯一的(实际上ORM并不在乎,只有数据库会在乎)。

1 个回答

暂无回答

撰写回答