Model definitions

We’ll use the following model definitions for our examples:

  1. import datetime
  2. from peewee import *
  3.  
  4.  
  5. db = SqliteDatabase(':memory:')
  6.  
  7. class BaseModel(Model):
  8. class Meta:
  9. database = db
  10.  
  11. class User(BaseModel):
  12. username = TextField()
  13.  
  14. class Tweet(BaseModel):
  15. content = TextField()
  16. timestamp = DateTimeField(default=datetime.datetime.now)
  17. user = ForeignKeyField(User, backref='tweets')
  18.  
  19. class Favorite(BaseModel):
  20. user = ForeignKeyField(User, backref='favorites')
  21. tweet = ForeignKeyField(Tweet, backref='favorites')

Peewee uses ForeignKeyField to define foreign-key relationshipsbetween models. Every foreign-key field has an implied back-reference, which isexposed as a pre-filtered Select query using the providedbackref attribute.

Creating test data

To follow along with the examples, let’s populate this database with some testdata:

  1. def populate_test_data():
  2. db.create_tables([User, Tweet, Favorite])
  3.  
  4. data = (
  5. ('huey', ('meow', 'hiss', 'purr')),
  6. ('mickey', ('woof', 'whine')),
  7. ('zaizee', ()))
  8. for username, tweets in data:
  9. user = User.create(username=username)
  10. for tweet in tweets:
  11. Tweet.create(user=user, content=tweet)
  12.  
  13. # Populate a few favorites for our users, such that:
  14. favorite_data = (
  15. ('huey', ['whine']),
  16. ('mickey', ['purr']),
  17. ('zaizee', ['meow', 'purr']))
  18. for username, favorites in favorite_data:
  19. user = User.get(User.username == username)
  20. for content in favorites:
  21. tweet = Tweet.get(Tweet.content == content)
  22. Favorite.create(user=user, tweet=tweet)

This gives us the following:

UserTweetFavorited by
hueymeowzaizee
hueyhiss
hueypurrmickey, zaizee
mickeywoof
mickeywhinehuey

Attention

In the following examples we will be executing a number of queries. If youare unsure how many queries are being executed, you can add the followingcode, which will log all queries to the console:

  1. import logging
  2. logger = logging.getLogger('peewee')
  3. logger.addHandler(logging.StreamHandler())
  4. logger.setLevel(logging.DEBUG)

Note

In SQLite, foreign keys are not enabled by default. Most things, includingthe Peewee foreign-key API, will work fine, but ON DELETE behaviour will beignored, even if you explicitly specify on_delete in yourForeignKeyField. In conjunction with the defaultAutoField behaviour (where deleted record IDs can be reused),this can lead to subtle bugs. To avoid problems, I recommend that youenable foreign-key constraints when using SQLite, by settingpragmas={'foreign_keys': 1} when you instantiate SqliteDatabase.

  1. # Ensure foreign-key constraints are enforced.
  2. db = SqliteDatabase('my_app.db', pragmas={'foreign_keys': 1})