这是我的代码。目标是将记录插入表中并使用两个连接的数值(用下划线分隔)作为主键。最终,这将由 item_number 和 datetime_checked (用下划线分隔)组成,但我已针对下面的示例代码对其进行了简化。
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 正在删除该下划线并将整数 4731
发送到数据库字段。如果你把它变成 pricecheck = "47_3__1"
或“47__3_1”,peewee 不会去掉下划线。您可以根据需要散布任意多个单下划线,它会将它们删除。如果一行中有多个下划线,则整个内容被视为一个字符串。如果有前导或尾随下划线,则将其视为字符串。
编辑:它肯定将其视为整数(或者可能是小数)。我尝试在下划线之外添加一个句点(即
772_1.2
),下划线被删除,但小数点仍然保留。我还测试了是否前导零被保留或删除。当存在单个下划线时(即 077_1
或 077_1.2
),前导零将被删除并删除下划线。这告诉我它正在将其视为小数或整数。但是如果存在双下划线 (077__1
),则不会删除前导零。
如果您在模型中将该字段视为
PrimaryKeyField
,则会发生此行为。如果您将其视为只是 TextField
,则不会发生这种情况(换句话说,即使它是多个数字之间的单个下划线,下划线也会保留)。
一种解决方法是不用担心它,因为 SQLite 只会存储该值,无论您在模式中如何定义它。另一种解决方法是在数字前面加上 alpha 值(即“a_47_3_1”)。另一种方法是根据设计将下划线加倍。但所有这些解决方法感觉就像创可贴。
但对我来说更大的问题是这种行为意味着我无法在主键中存储我需要的值。并且我只能存储大于
9223372036854775807
(有符号 64 位整数)的内容。
这种行为是否正确,只是我没有意识到?
主键字段中的下划线是某种中断字符吗?
为什么这种情况会发生在 PrimaryKeyField 上而不是 TextField 上?我假设 PrimaryKeyField (在 peewee ORM 中)并不关心内容是什么,只要输入的值是唯一的(实际上 ORM 不会关心,只有数据库会关心)。
PrimaryKeyField 是一个自动递增的整数字段。这不会失败的唯一原因是,默认情况下,Sqlite 不强制执行严格类型(因此您可以将文本存储在整数列中)。
如果想要文本,则需要制作文本主键:
pricecheck_id = TextField(primary_key=True)