Fields
- class
Field
([null=False[, index=False[, unique=False[, column_name=None[, default=None[, primary_key=False[, constraints=None[, sequence=None[, collation=None[, unindexed=False[, choices=None[, help_text=None[, verbose_name=None[, index_type=None]]]]]]]]]]]]]])
Parameters:
- null (bool) – Field allows NULLs.
- index (bool) – Create an index on field.
- unique (bool) – Create a unique index on field.
- column_name (str) – Specify column name for field.
- default – Default value (enforced in Python, not on server).
- primary_key (bool) – Field is the primary key.
- constraints (list) – List of constraints to apply to column, forexample:
[Check('price > 0')]
. - sequence (str) – Sequence name for field.
- collation (str) – Collation name for field.
- unindexed (bool) – Declare field UNINDEXED (sqlite only).
- choices (list) – An iterable of 2-tuples mapping column values todisplay labels. Used for metadata purposes only, to help whendisplaying a dropdown of choices for field values, for example.
- help_text (str) – Help-text for field, metadata purposes only.
- verbose_name (str) – Verbose name for field, metadata purposes only.
- index_type (str) – Specify index type (postgres only), e.g. ‘BRIN’.
Fields on a Model
are analogous to columns on a table.
field_type = '<some field type>'
Attribute used to map this field to a column type, e.g. “INT”. Seethe
FIELD
object in the source for more information.Retrieve a reference to the underlying
Column
object.The model the field is bound to.
The name of the field.
Coerce a Python value into a value suitable for storage in thedatabase. Sub-classes operating on special data-types will most likelywant to override this method.
Coerce a value from the database into a Python object. Sub-classesoperating on special data-types will most likely want to override thismethod.
- This method is a shorthand that is used, by default, by both
db_value()
andpython_value()
.
Parameters:value – arbitrary data from app or backendReturn type:python data type
Note
In SQLite, for performance reasons, the default primary key type simplyuses the max existing value + 1 for new values, as opposed to the maxever value + 1. This means deleted records can have their primary keysreused. In conjunction with SQLite having foreign keys disabled bydefault (meaning ON DELETE is ignored, even if you specify itexplicitly), this can lead to surprising and dangerous behaviour. Toavoid this, you may want to use one or both ofAutoIncrementField
and pragmas=[('foreign_keys', 'on')]
when you instantiate SqliteDatabase
.
Parameters:generate_always (bool) – if specified, then the identity will always begenerated (and specifying the value explicitly during INSERT will raisea programming error). Otherwise, the identity value is only generatedas-needed.
Field class for storing auto-incrementing primary keys using the newPostgres 10 IDENTITY column type. The column definition ends up lookinglike this:
- id = IdentityField()
- # "id" INT GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY
Attention
Only supported by Postgres 10.0 and newer.
- class
DecimalField
([max_digits=10[, decimal_places=5[, auto_round=False[, rounding=None[, **kwargs]]]]])
Parameters:
- max_digits (int) – Maximum digits to store.
- decimal_places (int) – Maximum precision.
- auto_round (bool) – Automatically round values.
- rounding –Defaults to
decimal.DefaultContext.rounding
.
Field class for storing decimal numbers. Values are represented asdecimal.Decimal
objects.
Note
Values that exceed length are not truncated automatically.
Note
Values that exceed length are not truncated automatically.
Usage:
- class Post(Model):
- content = TextField()
- flags = BitField()
- is_favorite = flags.flag(1)
- is_sticky = flags.flag(2)
- is_minimized = flags.flag(4)
- is_deleted = flags.flag(8)
- >>> p = Post()
- >>> p.is_sticky = True
- >>> p.is_minimized = True
- >>> print(p.flags) # Prints 4 | 2 --> "6"
- 6
- >>> p.is_favorite
- False
- >>> p.is_sticky
- True
We can use the flags on the Post class to build expressions in queries aswell:
- # Generates a WHERE clause that looks like:
- # WHERE (post.flags & 1 != 0)
- query = Post.select().where(Post.is_favorite)
- # Query for sticky + favorite posts:
- query = Post.select().where(Post.is_sticky & Post.is_favorite)
Parameters:value (int) – Value associated with flag, typically a power of 2.
Returns a descriptor that can get or set specific bits in the overallvalue. When accessed on the class itself, it returns aExpression
object suitable for use in a query.
If the value is not provided, it is assumed that each flag will be anincreasing power of 2, so if you had four flags, they would have thevalues 1, 2, 4, 8.
- class
BigBitField
- Field class for storing arbitrarily-large bitmaps in a
BLOB
. The fieldwill grow the underlying buffer as necessary, ensuring there are enoughbytes of data to support the number of bits of data being stored.
Example usage:
- class Bitmap(Model):
- data = BigBitField()
- bitmap = Bitmap()
- # Sets the ith bit, e.g. the 1st bit, the 11th bit, the 63rd, etc.
- bits_to_set = (1, 11, 63, 31, 55, 48, 100, 99)
- for bit_idx in bits_to_set:
- bitmap.data.set_bit(bit_idx)
- # We can test whether a bit is set using "is_set":
- assert bitmap.data.is_set(11)
- assert not bitmap.data.is_set(12)
- # We can clear a bit:
- bitmap.data.clear_bit(11)
- assert not bitmap.data.is_set(11)
- # We can also "toggle" a bit. Recall that the 63rd bit was set earlier.
- assert bitmap.data.toggle_bit(63) is False
- assert bitmap.data.toggle_bit(63) is True
- assert bitmap.data.is_set(63)
Parameters:idx (int) – Bit to set, indexed starting from zero.
Sets the idx-th bit in the bitmap.
Parameters:idx (int) – Bit to clear, indexed starting from zero.
Clears the idx-th bit in the bitmap.
Parameters:idx (int) – Bit to toggle, indexed starting from zero.Returns:Whether the bit is set or not.
Toggles the idx-th bit in the bitmap and returns whether the bit isset or not.
Example:
- >>> bitmap = Bitmap()
- >>> bitmap.data.toggle_bit(10) # Toggle the 10th bit.
- True
- >>> bitmap.data.toggle_bit(10) # This will clear the 10th bit.
- False
Parameters:idx (int) – Bit index, indexed starting from zero.Returns:Whether the bit is set or not.
Returns boolean indicating whether the idx-th bit is set or not.
- class
UUIDField
- Field class for storing
uuid.UUID
objects. With Postgres, theunderlying column’s data-type will be UUID. Since SQLite and MySQL do nothave a native UUID type, the UUID is stored as a VARCHAR instead.
- class
BinaryUUIDField
- Field class for storing
uuid.UUID
objects efficiently in 16-bytes. Usesthe database’s BLOB data-type (or VARBINARY in MySQL, or BYTEA inPostgres).
Parameters:formats (list) – A list of format strings to use when coercing a stringto a date-time.
Field class for storing datetime.datetime
objects.
Accepts a special parameter formats
, which contains a list of formatsthe datetime can be encoded with (for databases that do not have supportfor a native datetime data-type). The default supported formats are:
- '%Y-%m-%d %H:%M:%S.%f' # year-month-day hour-minute-second.microsecond
- '%Y-%m-%d %H:%M:%S' # year-month-day hour-minute-second
- '%Y-%m-%d' # year-month-day
Note
SQLite does not have a native datetime data-type, so datetimes arestored as strings. This is handled transparently by Peewee, but if youhave pre-existing data you should ensure it is stored asYYYY-mm-dd HH:MM:SS
or one of the other supported formats.
- Blog.select().where(Blog.pub_date.year == 2018)
month
Reference the month of the value stored in the column in a query.
Reference the day of the value stored in the column in a query.
Reference the hour of the value stored in the column in a query.
Reference the minute of the value stored in the column in a query.
Reference the second of the value stored in the column in a query.
- Method that returns a database-specific function call that will allowyou to work with the given date-time value as a numeric timestamp. Thiscan sometimes simplify tasks like date math in a compatible way.
Example:
- # Find all events that are exactly 1 hour long.
- query = (Event
- .select()
- .where((Event.start.to_timestamp() + 3600) ==
- Event.stop.to_timestamp())
- .order_by(Event.start))
Parameters:date_part (str) – year, month, day, hour, minute or second.Returns:expression node to truncate date/time to given resolution.
Truncates the value in the column to the given part. This method isuseful for finding all rows within a given month, for instance.
Parameters:formats (list) – A list of format strings to use when coercing a stringto a date.
Field class for storing datetime.date
objects.
Accepts a special parameter formats
, which contains a list of formatsthe datetime can be encoded with (for databases that do not have supportfor a native date data-type). The default supported formats are:
- '%Y-%m-%d' # year-month-day
- '%Y-%m-%d %H:%M:%S' # year-month-day hour-minute-second
- '%Y-%m-%d %H:%M:%S.%f' # year-month-day hour-minute-second.microsecond
Note
If the incoming value does not match a format, it is returned as-is.
- Person.select().where(Person.dob.year == 1983)
month
Reference the month of the value stored in the column in a query.
Reference the day of the value stored in the column in a query.
- See
DateTimeField.truncate()
. Note that only year, month,and day are meaningful forDateField
.
Parameters:formats (list) – A list of format strings to use when coercing a stringto a time.
Field class for storing datetime.time
objects (not timedelta
).
Accepts a special parameter formats
, which contains a list of formatsthe datetime can be encoded with (for databases that do not have supportfor a native time data-type). The default supported formats are:
- '%H:%M:%S.%f' # hour:minute:second.microsecond
- '%H:%M:%S' # hour:minute:second
- '%H:%M' # hour:minute
- '%Y-%m-%d %H:%M:%S.%f' # year-month-day hour-minute-second.microsecond
- '%Y-%m-%d %H:%M:%S' # year-month-day hour-minute-second
Note
If the incoming value does not match a format, it is returned as-is.
- evening_events = Event.select().where(Event.time.hour > 17)
minute
Reference the minute of the value stored in the column in a query.
- Reference the second of the value stored in the column in a query.
Parameters:
- resolution – Can be provided as either a power of 10, or as anexponent indicating how many decimal places to store.
- utc (bool) – Treat timestamps as UTC.
Field class for storing date-times as integer timestamps. Sub-secondresolution is supported by multiplying by a power of 10 to get an integer.
If the resolution
parameter is 0
or 1
, then the timestamp isstored using second resolution. A resolution between 2
and 6
istreated as the number of decimal places, e.g. resolution=3
correspondsto milliseconds. Alternatively, the decimal can be provided as a multipleof 10, such that resolution=10
will store 1/10th of a secondresolution.
The resolution
parameter can be either 0-6 or 10, 100, etc up to1000000 (for microsecond resolution). This allows sub-second precisionwhile still using an IntegerField
for storage. The default issecond resolution.
Also accepts a boolean parameter utc
, used to indicate whether thetimestamps should be UTC. Default is False
.
Finally, the field default
is the current timestamp. If you do not wantthis behavior, then explicitly pass in default=None
.
Parameters:coerce – Optional function to use for converting raw values into aspecific format.
Field class that does not specify a data-type (SQLite-only).
Since data-types are not enforced, you can declare fields without _any_data-type. It is also common for SQLite virtual tables to use meta-columnsor untyped columns, so for those cases as well you may wish to use anuntyped field.
Accepts a special coerce
parameter, a function that takes a valuecoming from the database and converts it into the appropriate Python type.
- class
ForeignKeyField
(model[, field=None[, backref=None[, on_delete=None[, on_update=None[, deferrable=None[, object_id_name=None[, lazy_load=True[, **kwargs]]]]]]]])
Parameters:
- model (Model) – Model to reference or the string ‘self’ if declaring aself-referential foreign key.
- field (Field) – Field to reference on
model
(default is primarykey). - backref (str) – Accessor name for back-reference, or “+” to disablethe back-reference accessor.
- on_delete (str) – ON DELETE action, e.g.
'CASCADE'
.. - on_update (str) – ON UPDATE action.
- deferrable (str) – Control when constraint is enforced, e.g.
'INITIALLY DEFERRED'
. - object_id_name (str) – Name for object-id accessor.
- lazy_load (bool) – Fetch the related object when the foreign-key fieldattribute is accessed (if it was not already loaded). If this isdisabled, accessing the foreign-key field will return the value storedin the foreign-key column.
Field class for storing a foreign key.
- class User(Model):
- name = TextField()
- class Tweet(Model):
- user = ForeignKeyField(User, backref='tweets')
- content = TextField()
- # "user" attribute
- >>> some_tweet.user
- <User: charlie>
- # "tweets" backref attribute
- >>> for tweet in charlie.tweets:
- ... print(tweet.content)
- Some tweet
- Another tweet
- Yet another tweet
For an in-depth discussion of foreign-keys, joins and relationships betweenmodels, refer to Relationships and Joins.
Note
Foreign keys do not have a particular field_type
as they will taketheir field type depending on the type of primary key on the model theyare related to.
Note
If you manually specify a field
, that field must be either aprimary key or have a unique constraint.
Note
Take care with foreign keys in SQLite. By default, ON DELETE has noeffect, which can have surprising (and usually unwanted) effects onyour database integrity. This can affect you even if you don’t specifyon_delete
, since the default ON DELETE behaviour (to fail withoutmodifying your data) does not happen, and your data can be silentlyrelinked. The safest thing to do is to specifypragmas={'foreign_keys': 1}
when you instantiateSqliteDatabase
.
Parameters:rel_model_name (str) – Model name to reference.
Field class for representing a deferred foreign key. Useful for circularforeign-key references, for example:
- class Husband(Model):
- name = TextField()
- wife = DeferredForeignKey('Wife', deferrable='INITIALLY DEFERRED')
- class Wife(Model):
- name = TextField()
- husband = ForeignKeyField(Husband, deferrable='INITIALLY DEFERRED')
In the above example, when the Wife
model is declared, the foreign-keyHusband.wife
is automatically resolved and turned into a regularForeignKeyField
.
Warning
DeferredForeignKey
references are resolved when modelclasses are declared and created. This means that if you declare aDeferredForeignKey
to a model class that has already beenimported and created, the deferred foreign key instance will never beresolved. For example:
- class User(Model):
- username = TextField()
- class Tweet(Model):
- # This will never actually be resolved, because the User
- # model has already been declared.
- user = DeferredForeignKey('user', backref='tweets')
- content = TextField()
In cases like these you should use the regularForeignKeyField
or you can manually resolve deferredforeign keys like so:
- # Tweet.user will be resolved into a ForeignKeyField:
- DeferredForeignKey.resolve(User)
- class
ManyToManyField
(model[, backref=None[, through_model=None[, on_delete=None[, on_update=None]]]])
Parameters:
- model (Model) – Model to create relationship with.
- backref (str) – Accessor name for back-reference
- through_model (Model) –
Model
to use for the intermediarytable. If not provided, a simple through table will be automaticallycreated. - on_delete (str) – ON DELETE action, e.g.
'CASCADE'
. Will be usedfor foreign-keys in through model. - on_update (str) – ON UPDATE action. Will be used for foreign-keys inthrough model.
The ManyToManyField
provides a simple interface for workingwith many-to-many relationships, inspired by Django. A many-to-manyrelationship is typically implemented by creating a junction table withforeign keys to the two models being related. For instance, if you werebuilding a syllabus manager for college students, the relationship betweenstudents and courses would be many-to-many. Here is the schema usingstandard APIs:
Attention
This is not a field in the sense that there is no column associatedwith it. Rather, it provides a convenient interface for accessing rowsof data related via a through model.
Standard way of declaring a many-to-many relationship (without the use ofthe ManyToManyField
):
- class Student(Model):
- name = CharField()
- class Course(Model):
- name = CharField()
- class StudentCourse(Model):
- student = ForeignKeyField(Student)
- course = ForeignKeyField(Course)
To query the courses for a particular student, you would join through thejunction table:
- # List the courses that "Huey" is enrolled in:
- courses = (Course
- .select()
- .join(StudentCourse)
- .join(Student)
- .where(Student.name == 'Huey'))
- for course in courses:
- print(course.name)
The ManyToManyField
is designed to simplify this use-case byproviding a field-like API for querying and modifying data in thejunction table. Here is how our code looks usingManyToManyField
:
- class Student(Model):
- name = CharField()
- class Course(Model):
- name = CharField()
- students = ManyToManyField(Student, backref='courses')
Note
It does not matter from Peewee’s perspective which model theManyToManyField
goes on, since the back-reference is justthe mirror image. In order to write valid Python, though, you will needto add the ManyToManyField
on the second model so that the name ofthe first model is in the scope.
We still need a junction table to store the relationships between studentsand courses. This model can be accessed by calling theget_through_model()
method. This is useful whencreating tables.
- # Create tables for the students, courses, and relationships between
- # the two.
- db.create_tables([
- Student,
- Course,
- Course.students.get_through_model()])
When accessed from a model instance, the ManyToManyField
exposes a ModelSelect
representing the set of related objects.Let’s use the interactive shell to see how all this works:
- >>> huey = Student.get(Student.name == 'huey')
- >>> [course.name for course in huey.courses]
- ['English 101', 'CS 101']
- >>> engl_101 = Course.get(Course.name == 'English 101')
- >>> [student.name for student in engl_101.students]
- ['Huey', 'Mickey', 'Zaizee']
To add new relationships between objects, you can either assign the objectsdirectly to the ManyToManyField
attribute, or call theadd()
method. The difference between the two isthat simply assigning will clear out any existing relationships, whereasadd()
can preserve existing relationships.
- >>> huey.courses = Course.select().where(Course.name.contains('english'))
- >>> for course in huey.courses.order_by(Course.name):
- ... print course.name
- English 101
- English 151
- English 201
- English 221
- >>> cs_101 = Course.get(Course.name == 'CS 101')
- >>> cs_151 = Course.get(Course.name == 'CS 151')
- >>> huey.courses.add([cs_101, cs_151])
- >>> [course.name for course in huey.courses.order_by(Course.name)]
- ['CS 101', 'CS151', 'English 101', 'English 151', 'English 201',
- 'English 221']
This is quite a few courses, so let’s remove the 200-level english courses.To remove objects, use the remove()
method.
- >>> huey.courses.remove(Course.select().where(Course.name.contains('2'))
- 2
- >>> [course.name for course in huey.courses.order_by(Course.name)]
- ['CS 101', 'CS151', 'English 101', 'English 151']
To remove all relationships from a collection, you can use theclear()
method. Let’s say that English 101 iscanceled, so we need to remove all the students from it:
- >>> engl_101 = Course.get(Course.name == 'English 101')
- >>> engl_101.students.clear()
Note
For an overview of implementing many-to-many relationships usingstandard Peewee APIs, check out the Implementing Many to Many section. For allbut the most simple cases, you will be better off implementingmany-to-many using the standard APIs.
through_model
The
Model
representing the many-to-many junction table.Will be auto-generated if not explicitly declared.
Parameters:
- **value** – Either a [<code>Model</code>](#Model) instance, a list of modelinstances, or a [<code>SelectQuery</code>](#SelectQuery).
- **clear_existing** (_bool_) – Whether to remove existing relationships.
Associate value
with the current instance. You can pass in a singlemodel instance, a list of model instances, or even a ModelSelect
.
Example code:
- # Huey needs to enroll in a bunch of courses, including all
- # the English classes, and a couple Comp-Sci classes.
- huey = Student.get(Student.name == 'Huey')
- # We can add all the objects represented by a query.
- english_courses = Course.select().where(
- Course.name.contains('english'))
- huey.courses.add(english_courses)
- # We can also add lists of individual objects.
- cs101 = Course.get(Course.name == 'CS 101')
- cs151 = Course.get(Course.name == 'CS 151')
- huey.courses.add([cs101, cs151])
Parameters:value – Either a Model
instance, a list of modelinstances, or a ModelSelect
.
Disassociate value
from the current instance. Likeadd()
, you can pass in a model instance, alist of model instances, or even a ModelSelect
.
Example code:
- # Huey is currently enrolled in a lot of english classes
- # as well as some Comp-Sci. He is changing majors, so we
- # will remove all his courses.
- english_courses = Course.select().where(
- Course.name.contains('english'))
- huey.courses.remove(english_courses)
- # Remove the two Comp-Sci classes Huey is enrolled in.
- cs101 = Course.get(Course.name == 'CS 101')
- cs151 = Course.get(Course.name == 'CS 151')
- huey.courses.remove([cs101, cs151])
Example code:
- # English 101 is canceled this semester, so remove all
- # the enrollments.
- english_101 = Course.get(Course.name == 'English 101')
- english_101.students.clear()
get_through_model
()- Return the
Model
representing the many-to-many junctiontable. This can be specified manually when the field is beinginstantiated using thethrough_model
parameter. If athrough_model
is not specified, one will automatically be created.
When creating tables for an application that usesManyToManyField
, you must create the through table expicitly.
- # Get a reference to the automatically-created through table.
- StudentCourseThrough = Course.students.get_through_model()
- # Create tables for our two models as well as the through model.
- db.create_tables([
- Student,
- Course,
- StudentCourseThrough])
- class
DeferredThroughModel
- Place-holder for a through-model in cases where, due to a dependency, youcannot declare either a model or a many-to-many field without introducingNameErrors.
Example:
- class Note(BaseModel):
- content = TextField()
- NoteThroughDeferred = DeferredThroughModel()
- class User(BaseModel):
- username = TextField()
- notes = ManyToManyField(Note, through_model=NoteThroughDeferred)
- # Cannot declare this before "User" since it has a foreign-key to
- # the User model.
- class NoteThrough(BaseModel):
- note = ForeignKeyField(Note)
- user = ForeignKeyField(User)
- # Resolve dependencies.
- NoteThroughDeferred.set_model(NoteThrough)
Parameters:field_names – Names of fields that comprise the primary key.
A primary key composed of multiple columns. Unlike the other fields, acomposite key is defined in the model’s Meta
class after the fieldshave been defined. It takes as parameters the string names of the fields touse as the primary key:
- class BlogTagThrough(Model):
- blog = ForeignKeyField(Blog, backref='tags')
- tag = ForeignKeyField(Tag, backref='blogs')
- class Meta:
- primary_key = CompositeKey('blog', 'tag')