Auto-incrementing IDs are, as their name says, automatically generated for you when you insert a new row into the database. When you call , peewee determines whether to do an INSERT versus an UPDATE based on the presence of a primary key value. Since, with our uuid example, the database driver won’t generate a new ID, we need to specify it manually. When we call save() for the first time, pass in force_insert = True
:
# This works because .create() will specify `force_insert=True`.
obj1 = UUIDModel.create(id=uuid.uuid4())
# This will not work, however. Peewee will attempt to do an update:
obj2 = UUIDModel(id=uuid.uuid4())
obj2.save() # WRONG
# Once the object has been created, you can call save() normally.
obj2.save()
Note
Any foreign keys to a model with a non-integer primary key will have a ForeignKeyField
use the same underlying storage type as the primary key they are related to.
Warning
Peewee does not support foreign-keys to models that define a CompositeKey primary key. If you wish to add a foreign-key to a model that has a composite primary key, replicate the columns on the related model and add a custom accessor (e.g. a property).
Sometimes you do not want the database to automatically generate a value for the primary key, for instance when bulk loading relational data. To handle this on a one-off basis, you can simply tell peewee to turn off auto_increment
during the import:
data = load_user_csv() # load up a bunch of data
User._meta.auto_increment = False # turn off auto incrementing IDs
with db.atomic():
for row in data:
u = User(id=row[0], username=row[1])
u.save(force_insert=True) # <-- force peewee to insert row
If you always want to have control over the primary key, simply do not use the PrimaryKeyField
field type, but use a normal IntegerField
(or other column type):
class User(BaseModel):
id = IntegerField(primary_key=True)
>>> u = User.create(id=999, username='somebody')
>>> u.id
999
>>> User.get(User.username == 'somebody').id
999
If you wish to create a model with no primary key, you can specify primary_key = False
in the inner Meta
class:
This will yield the following DDL:
CREATE TABLE "mydata" (
"timestamp" DATETIME NOT NULL,
)
Some model APIs may not work correctly for models without a primary key, for instance and delete_instance()
(you can instead use , update()
and ).