Here is my code. The goal is to insert a record into a table and to use two concatenated numeric values (separated with an underscore) as the primary key. Ultimately, this will be made up of an item_number and the datetime_checked (separated with an underscore), but I have simplified it for this sample code below.

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()

Issue:

You'll see the pricecheck = "47_3_1" on line 20. Peewee is stripping that underscore out and sending the integer 4731 to the database field. If you make that into pricecheck = "47_3__1" or "47__3_1", peewee does not strip out the underscores. You can intersperse as many single underscores as you want and it will strip them out. If there are multiple underscores in a row, the whole thing is a treated as a string. And if there are leading or trailing underscores, it is treated as a string.

EDIT: It's definitely treating it as an integer (or, probably, decimal. I tried adding a period later beyond the underscore (i.e. 772_1.2) and the underscore was stripped out but the decimal point remained. I also tested if a leading zero is left in place or removed. When a single underscore is present (i.e. 077_1 or 077_1.2 for that matter), the leading zero is dropped and the underscore is removed. Which tells me it is treating it as a decimal or integer. But with a double underscore present (077__1), the leading zero is not removed.

This behavior happens if you treat the field as PrimaryKeyField in the Model. If you treat it as just TextField, it does not happen (in other words, the underscore stays even if it is a single underscore between several numbers).

One workaround is to not worry about it since SQLite will just store the value however you have it defined in the schema. Another workaround would be to prefix the numberic with an alpha value (i.e. "a_47_3_1"). Another would be to double the underscore, by design. But all of these workarounds feel like bandaids.

But the bigger issue for me is that this behavior means I'm not getting to store the value I need in the primary key. AND I'm limited to storing nothing larger than 9223372036854775807 (signed 64-bit integer).

Is this behavior correct and I'm just not aware of it?

Is the underscore, in a primary key field, some sort of break character?

Why would this happen on the PrimaryKeyField but not on a TextField? I assume that PrimaryKeyField (in the peewee ORM) doesn't care what the contents are so long as the value going in is unique (and really the ORM wouldn't care, only the DB would care).

0

There are 0 best solutions below