Model API (smells like django) — peewee v0.7.1 documentation

### Navigation

- index
- next |
- previous |
- peewee v0.7.1 documentation »

# Model API (smells like django)

Models and their fields map directly to database tables and columns. Consider the following:

    from peewee import *

    db = SqliteDatabase('test.db')

    # create a base model class that our application's models will extend
    class BaseModel(Model):
        class Meta:
            database = db

    class Blog(BaseModel):
        name = peewee.CharField() # <-- VARCHAR

    class Entry(BaseModel):
        headline = peewee.CharField()
        content = peewee.TextField() # <-- TEXT
        pub_date = peewee.DateTimeField() # <-- DATETIME
        blog = peewee.ForeignKeyField() # <-- INTEGER referencing the Blog table

This is a typical example of how to specify models with peewee. There are several things going on:

1. Create an instance of a `Database`

   >     db = SqliteDatabase('test.db')

   > This establishes an object, `db`, which is used by the models to connect to and query the database. There can be multiple database instances per application, but, as I hope is obvious, `ForeignKeyField` related models must be on the same database.

2. Create a base model class which specifies our database

   >     class BaseModel(Model):
   >         class Meta:
   >             database = db

   > Model configuration is kept namespaced in a special class called `Meta` – this convention is borrowed from Django, which does the same thing. `Meta` configuration is passed on to subclasses, so this code basically allows all our project’s models to connect to our database.

3. Declare a model or two

   >     class Blog(BaseModel):
   >         name = peewee.CharField()

   > Model definition is pretty similar to django or sqlalchemy – you basically define a class which represents a single table in the database, then its attributes (which are subclasses of `Field`) represent columns.

## Creating tables

In order to start using these models, its necessary to open a connection to the database and create the tables first:

    # connect to our database
    db.connect()

    # create the tables
    Blog.create_table()
    Entry.create_table()

Note

Strictly speaking, the explicit call to `connect()` is not necessary, but it is good practice to be explicit about when you are opening and closing connections.

## Model instances

Assuming you’ve created the tables and connected to the database, you are now free to create models and execute queries.

Creating models in the interactive interpreter is a snap.

1. Use the `Model.create()` classmethod:

   >     >>> blog = Blog.create(name='Funny pictures of animals blog')
   >     >>> entry = Entry.create(
   >     ...     headline='maru the kitty',
   >     ...     content='http://www.youtube.com/watch?v=xdhLQCYQ-nQ',
   >     ...     pub_date=datetime.datetime.now(),
   >     ...     blog=blog
   >     ... )

   >     >>> entry.blog.name
   >     'Funny pictures of animals blog'

2. Build up the instance programmatically:

   >     >>> blog = Blog()
   >     >>> blog.name = 'Another sweet blog'
   >     >>> blog.save()

### Traversing foriegn keys

As you can see from above, the foreign key from `Entry` to `Blog` can be traversed automatically:

    >>> entry.blog.name
    'Funny pictures of animals blog'

The reverse is also true, we can iterate a `Blog` objects associated `Entries`:

    >>> for entry in blog.entry_set:
    ...     print entry.headline
    ...
    maru the kitty

Under the hood, the `entry_set` attribute is just a `SelectQuery`:

    >>> blog.entry_set
    <peewee.SelectQuery object at 0x151f510>

    >>> blog.entry_set.sql()
    ('SELECT * FROM entry WHERE blog_id = ?', [1])

## Model options

In order not to pollute the model namespace, model-specific configuration is placed in a special class called `Meta`, which is a convention borrowed from the django framework:

    from peewee import *

    custom_db = SqliteDatabase('custom.db')

    class CustomModel(Model):
        class Meta:
            database = custom_db

This instructs peewee that whenever a query is executed on `CustomModel` to use the custom database.

Note

Take a look at the sample models - you will notice that we created a `BaseModel` that defined the database, and then extended. This is the preferred way to define a database and create models.

## Model methods

class `Model`
  `save`()

    Save the given instance, creating or updating depending on whether it has a primary key.

    example:

        >>> some_obj.title = 'new title' # <-- does not touch the database
        >>> some_obj.save() # <-- change is persisted to the db

  classmethod `create`(**attributes)

    Parameters: | attributes – key/value pairs of model attributes

    Create an instance of the `Model` with the given attributes set.

    example:

        >>> user = User.create(username='admin', password='test')

  classmethod `filter`(*args, **kwargs)

    Parameters: | args – a list of `Q` or `Node` objects kwargs – a mapping of column + lookup to value, e.g. “age__gt=55”
    Return type: | `SelectQuery` with appropriate `WHERE` clauses

    Provides a django-like syntax for building a query. The key difference between `filter()` and `SelectQuery.where()` is that `filter()` supports traversing joins using django’s “double-underscore” syntax:

        >>> sq = Entry.filter(blog__title='Some Blog')

    This method is chainable:

        >>> base_q = User.filter(active=True)
        >>> some_user = base_q.filter(username='charlie')

  classmethod `get`(*args, **kwargs)

    Parameters: | args – a list of `Q` or `Node` objects kwargs – a mapping of column + lookup to value, e.g. “age__gt=55”
    Return type: | `Model` instance or raises `DoesNotExist` exception

    Get a single row from the database that matches the given query. Raises a `<model-class>.DoesNotExist` if no rows are returned:

        >>> user = User.get(username=username, password=password)

    This method is also expose via the `SelectQuery`:

        >>> active = User.select().where(active=True)
        >>> try:
        ...     user = active.get(username=username, password=password)
        ... except User.DoesNotExist:
        ...     user = None

  classmethod `get_or_create`(**attributes)

    Parameters: | attributes – key/value pairs of model attributes
    Return type: | a `Model` instance

    Get the instance with the given attributes set. If the instance does not exist it will be created.

    example:

        >>> CachedObj.get_or_create(key=key, val=some_val)

  classmethod `select`(query=None)

    Return type: | a `SelectQuery` for the given `Model`

    example:

        >>> User.select().where(active=True).order_by('username')

  classmethod `update`(**query)

    Return type: | an `UpdateQuery` for the given `Model`

    example:

        >>> q = User.update(active=False).where(registration_expired=True)
        >>> q.sql()
        ('UPDATE user SET active=? WHERE registration_expired = ?', [0, 1])
        >>> q.execute() # <-- execute it

  classmethod `delete`(**query)

    Return type: | a `DeleteQuery` for the given `Model`

    example:

        >>> q = User.delete().where(active=False)
        >>> q.sql()
        ('DELETE FROM user WHERE active = ?', [0])
        >>> q.execute() # <-- execute it

    Warning

    Assume you have a model instance – calling `model_instance.delete()` does not delete it.

  classmethod `insert`(**query)

    Return type: | an `InsertQuery` for the given `Model`

    example:

        >>> q = User.insert(username='admin', active=True, registration_expired=False)
        >>> q.sql()
        ('INSERT INTO user (username,active,registration_expired) VALUES (?,?,?)', ['admin', 1, 0])
        >>> q.execute()
        1

  classmethod `create_table`([fail_silently=False])

    Parameters: | fail_silently – If set to `True`, the method will check for the existence of the table before attempting to create.

    Create the table for the given model.

    example:

        >>> database.connect()
        >>> SomeModel.create_table() # <-- creates the table for SomeModel

  classmethod `drop_table`([fail_silently=False])

    Parameters: | fail_silently – If set to `True`, the query will check for the existence of the table before attempting to remove.

    Drop the table for the given model.

    Note

    Cascading deletes are not handled by this method, nor is the removal of any constraints.

  classmethod `table_exists`()

    Return type: | Boolean whether the table for this model exists in the database