Class Base
source code
object --+
|
Base
The Base class for all models using pyperry.
Base defines
the functionality of a pyperry model. All models should inherit
(directly or indirectly) from Base. For a basic overview of usage, check out the docs
on the pyperry module.
Configuration Overview
Configuration is done through various class methods on the model.
These could be set anywhere, but conventionally they are set in a
config method on the class. This method is run when a
class is created with the newly created class as an argument. Thus,
configuration can be done like this:
class Animal(pyperry.base.Base):
def config(cls):
cls.attributes 'id', 'name', 'mammal'
cls.configure('read', type='bertrpc')
cls.add_middleware('read', MyMiddleware, config1='val')
cls.has_many('friendships', class_name='Friendship')
cls.scope('mammal', where={ 'mammal': true })
Any class configuration can be done in this method.
Querying
Queries can be built by chaining calls to scopes or query methods.
For example:
Person.where({ 'first_name': 'Bob' }).order('last_name')
This generates a query for all Person objects with the first name
"Bob" ordered by their last name. Each query method returns
a new Relation object with the new query parameters applied.
This allows the continued chaining.
A Relation object is a sequence-like object behaving
much like a list. The query will be run the first time
the object is treated like a list, and the records will be used for the
expression. For example:
query = Animal.where({ 'type': 'Platypus' })
# Array comprehensions and for loops
for animal in query:
print animal.name + " is a platypus. They don't do much."
# Compares type and attributes of objects for equality
object in query
object not in query
# Indexing, slicing, step slicing
query[0]
query[0:3]
query[0:3:2]
# Other
len(query)
In this example the query is executed before running the for loop,
and all subsequent calls use that result. Queries will not be run
until you need them so unused queries don't hurt performance. If you
would like to force a query to run and retreive the records in a
list object use the Relation.all() method, or to receive the object itself
in single result queries use the Relation.first() method.
Persistence
Pyperry provides an interface for creating, updating, and deleting
models when a write adapter is configured. A model can be initialized
as a "new" record (default) or a "stored" record
and is determined by the new_record attribute. This
changes the behavior of the save operation. A "new" record is
created and a "stored" record is updated. Also, a
"new" record cannot be deleted as it does not yet exist in
the database. See the individual persistence
methods for more information
Scopes
Scopes allow you to specify prebuilt views of your data. Scopes,
like query methods, can be applied simply by chaining calls on
instances of Relation or the Base class. Scopes are created through the scope()
class method (conventionally within the _config method):
cls.scope('ordered', order='type, name')
cls.scope('platypus', where={ 'type': 'platypus' })
cls.scope('perrys', where={ 'name': 'perry' })
cls.scope('agentp', cls.perrys().platypus())
These scopes can now be used in queries along with query methods and
chained together to make powerful queries:
# Ordered animals with type 'platypus' named 'perry'
Animal.ordered().agentp()
Scopes can also accept arguments by defining a lambda or function to
be called when the scope is invoked:
@cls.scope
def name_is(rel, name):
return rel.where({ 'name': name })
# This can also be written:
cls.scope('name_is', lambda(rel, name): rel.where({ 'name': name }))
# This allows:
Animal.name_is('perry')
Associations
Associations allow you to define foreign key relationships between
two models, the target (model on which the association is defined) and
the source (model from which the data will come). There are two basic
kinds of associations: has and belongs. A has relationship means the
foreign_key lives on the source model. A belongs relationship means
the foreign_key lives on target model.
Imagine a blog. A blog has many articles and an article belongs to
an author. You might model this structure with Blog, Article and
Person classes. Associations are conventionally defined in the
_config method for each class, but to save space we'll
just show the association definition for each class:
Blog.has_many('articles', class_name='Article')
Article.belongs_to('blog', class_name='Blog')
Article.belongs_to('author', class_name='Person')
Assuming you have an instance of Blog called
blog you could then reference these associations like
this:
# An ordered list of articles on this blog
articles = blog.authors().ordered()
# The author of the first article
articles[0].author()
Note that the has_many association returns a Relation
object allowing you to apply query methods and scopes to the
association before executing the query.
For more information on Associations see the individual association
methods.
|
|
__init__(self,
attributes={},
new_record=True,
**kwargs)
Initialize a new pyperry object with attributes |
source code
|
|
|
|
reload(self)
Refetch the attributes for this object from the read adapter |
source code
|
|
|
|
frozen(self)
Returns True if this instance is frozen and cannot be saved. |
source code
|
|
|
|
freeze(self)
Marks this instance as being frozen, which will cause all future
writes and deletes to fail. |
source code
|
|
|
|
|
|
|
__eq__(self,
compare)
Compare equality of an object by its attributes |
source code
|
|
|
Inherited from object:
__delattr__,
__format__,
__getattribute__,
__hash__,
__new__,
__reduce__,
__reduce_ex__,
__sizeof__,
__str__,
__subclasshook__
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pk_attr(self)
A shortcut method from retrieving the name of this model's primary
key attribute. |
source code
|
|
|
|
pk_value(self)
A shortcut method for retrieving the value stored in this model's
primary key attribute. |
source code
|
|
|
|
|
|
|
save(self)
Save the current value of the model's data attributes through the
write adapter. |
source code
|
|
|
|
update_attributes(self,
attributes=None,
**kwargs)
Update the attributes with the given dictionary or keywords and save
the model. |
source code
|
|
|
|
|
|
|
|
|
|
|
|
|
configure(cls,
adapter_type,
config=None,
**kwargs)
Method for setting adapter configuration options. |
source code
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
primary_key(cls)
Returns the attribute name of the model's primary key. |
source code
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
scope(cls,
name_or_func,
*args,
**kwargs)
Defines a scope on the given model. |
source code
|
|
|
|
|
|
|
|
|
|
|
|
|
adapter_config = {}
|
|
|
defined_associations = {}
|
|
|
defined_attributes = set([])
|
|
Inherited from object:
__class__
|
__init__(self,
attributes={},
new_record=True,
**kwargs)
(Constructor)
| source code
|
Initialize a new pyperry object with attributes
Uses attributes dictionary to set attributes on a new
instance. Only keys that have been defined for the model will be set.
Defaults to a new record but can be overriden with
new_record param. You can also use kwargs to
specify the attributes.
- Parameters:
attributes - dictionary of attributes to set on the new instance
new_record - set new_record flag to True or False.
- Overrides:
object.__init__
|
|
Adds dict like attribute reading
Allows:
person['id']
person['name']
Developer Note: This method of accessing attributes is used
internally and should never be overridden by subclasses.
- Parameters:
key - name of the attribute to get
- Raises:
KeyError - If key is not a defined attribute.
|
__setitem__(self,
key,
value)
(Index assignment operator)
| source code
|
Adds dict like attribute writing
Allows:
animal['name'] = 'Perry'
animal['type'] = 'Platypus'
- Parameters:
key - name of the attribute to set
value - value to set key attribute to
- Raises:
KeyError - If key is not a defined attribute.
|
__getattr__(self,
key)
(Qualification operator)
| source code
|
Dynamic attribute / association reading
Properties or Methods are not created for attributes or associations,
and are instead handled by this method. This allows a model to override
the default behavior of attribute or association access by creating a
property or method (respectively) of the same name.
Allows:
animal.name
animal.friends()
- Parameters:
key - name of the attribute attempting to be accessed
- Raises:
AttributeError - if key is not a defined attribute or association.
|
|
Dynamic attribute setting
Properties are not created for setting attributes. This method allows
setting any defined attributes through the standard writer interface.
Allows:
animal.name = "Perry"
animal.type = "Platypus
- Parameters:
key - name of the attribute to set
value - value to set the key attribute to
- Overrides:
object.__setattr__
|
|
Set the attributes of the object using the provided dictionary.
Only attributes defined using define_attributes will be set.
- Parameters:
attributes - dictionary of attributes
|
|
Save the current value of the model's data attributes through the
write adapter.
If the save succeeds, the model's saved attribute will be
set to True. Also, if a read adapter is configured, the models data
attributes will be refreshed to ensure that you have the current
values.
If the save fails, the model's errors will be set to a
dictionary containing error messages and the saved attribute
will be set to False.
- Returns:
- Returns
True on success or False on
failure
|
update_attributes(self,
attributes=None,
**kwargs)
| source code
|
Update the attributes with the given dictionary or keywords and save
the model.
Has the same effect as calling:
obj.set_attributes(attributes)
obj.save()
Requires either attributes or keyword arguments. If both
are provicded, attributes will be used and
kwargs will be ignored.
- Parameters:
attributes - dictionary of attributes to set
kwargs - Optionally use keyword syntax instead of attributes
- Returns:
- Returns
True on success or False on
failure
|
|
Removes this model from the data store
If the call succeeds, the model will be marked as frozen and calling
frozen on the model will return True. Once a model is
frozen, an exception will be raised if you attempt to call one of the
persistence methods on it.
If the call fails, the model's errors attribute will be
set to a dictionary of error messages describing the error.
- Returns:
True on success or False on failure
|
configure(cls,
adapter_type,
config=None,
**kwargs)
Class Method
| source code
|
Method for setting adapter configuration options.
Accepts a dictionary argument or keyword arguments, but not both.
Configuration specified will be merged with all previous calls to
configure for this adapter_type
- Parameters:
adapter_type - specify the type of adapter ('read' or 'write')
config - dictionary of configuration parameters
kwargs - alternate specification of configuration
|
add_middleware(cls,
adapter_type,
klass,
options=None,
**kwargs)
Class Method
| source code
|
Add a middleware to the given adapter
Interface for appending a middleware to an adapter stack. For more
information on middlewares see docs on pyperry.adapter.abstract_adapter.AbstractAdapter.
- Parameters:
adapter_type - specify type of adapter ('read' or 'write')
klass - specify the class to use as the middleware
options - specify an options dictionary to pass to middleware
kwargs - specify options with keyword arguments instead of options.
|
add_processor(cls,
adapter_type,
klass,
options=None,
**kwargs)
Class Method
| source code
|
Add a processor to the given adapter
Interface for adding a processor to the adapter stack. Processors come
before the middleware in the adapter stack. For more information on
processors see docs on pyperry.adapter.abstract_adapter.AbstractAdapter.
- Parameters:
adapter_type - specify type of adapter ('read' or 'write')
klass - specify the class to use as the processor
options - specify an options dictionary to pass to processor
kwargs - specify options with keyword arguments instead of options.
|
|
Returns the adapter specified by adapter_type
If the adapter has not been configured correctly
ConfigurationError will be raised.
- Parameters:
adapter_type - type of adapter ('read' or 'write')
- Returns:
- the adapter specified by
adapter_type
|
define_attributes(cls,
*attributes)
Class Method
| source code
|
Define available attributes for a model.
This method is automatically called when the attributes var is set on
the class during definition. Each call will union any new attributes
into the set of defined attributes.
aliased as attributes
- Parameters:
attributes - list parameters as strings, or the first argument is a list of
strings.
|
|
Define available attributes for a model.
This method is automatically called when the attributes var is set on
the class during definition. Each call will union any new attributes
into the set of defined attributes.
aliased as attributes
- Parameters:
attributes - list parameters as strings, or the first argument is a list of
strings.
|
set_primary_key(cls,
attr_name)
Class Method
| source code
|
Set the name of the primary key attribute for the model. The new
primary key attribute must be one of the definted attributes otherwise
set_primary_key will raise an AttributeError.
|
|
Execute query using relation on the read adapter stack
- Parameters:
relation - An instance of Relation describing the query
- Returns:
- list of records from adapter query data each with new_record set
to false.
None items are removed.
|
|
A base instance of Relation for this model.
All query scopes originate from this instance, and should not change
this instance.
- Returns:
Relation instance for this model
|
|
Base instance of Relation after default scopes are
applied.
Returns an instance of Relation after applying the latest scope in the
class variable _scoped_methods.
- Returns:
Relation instance with default scopes applied if
default scopes are present. Otherwise returns None.
|
|
Unique instance of Relation to build queries on.
If you want an instance of relation on this model you most likely want
this method.
- Returns:
- Cloned return value from
current_scope or
relation
|
default_scope(cls,
*args,
**kwargs)
Class Method
| source code
|
Add a default scoping for this model.
All queries will be built based on the default scope of this model.
Only specify a default scope if you always want the scope applied.
Calls to default_scope aggregate. So each call will append
to options from previous calls.
Note: You can bypass default scopings using the unscoped
method.
Similar to arguments accepted by scope. The
only thing not supported is lambdas/functions accepting additional
arguments. Here are some examples:
Model.default_scope(where={'type': 'Foo'})
Model.default_scope({ 'order': 'name DESC' })
|
|
Execute function without default scopes
All default scoping is temporarily removed and the given function is
then executed. After the function is executed all previous default
scopes are applied.
- Parameters:
function - function to execute
|
scope(cls,
name_or_func,
*args,
**kwargs)
Class Method
| source code
|
Defines a scope on the given model.
A scope can be defined in one of several ways:
Dictionary or Keyword Arguments
If your scope is simply setting a few static query arguments than this
is the easiest option. Here are a few examples:
# With a dictionary
Model.scope('ordered', { 'order': "name" })
# With keyword arguments
Model.scope('awesome', where={'awesome': 1})
Model.scope('latest', order="created_at DESC", limit=1)
With a Lambda or Function
When your scope involves chaining other scopes, delayed values (such
as a relative time), or if it takes arguments then this is the preferred
method. Here are a few examples:
Model.scope('awesome_ordered', lambda(cls): cls.ordered().awesome())
# Returns a scope dynamically generating condition using fictional
# minutes_ago function. Without the lambda this wouldn't update
# each time the scope is used, but only when the code was reloaded.
Model.scope('recent', lambda(cls): cls.where(
'created_at > %s' % minutes_ago(5))
# You can also use the method as a decorator! Whatever you call
# your method will be the name of the scope. Make sure it's unique.
@Model.scope
def name_like(cls, word):
return cls.where(["name LIKE '%?%", word])
These scopes can be chained. Like so:
# Returns a max of 5 records that have a name containing 'bob'
# ordered
Model.name_like('bob').ordered().limit(5)
|
|
Create a belongs association
Defines a belongs association by the name specified by
id, and you can access the association through a method by
this name will be created. A call to this method will run the query for
this association and return the result, or, if this query has been run
previously (or if it was eager loaded), it will return the cached
result.
In addition to keywords listed below this method also accepts all of
the query finder options specified on Relation
- Parameters:
id - name of the association
class_name - Unambiguous name (string) of source class (required).
klass - Can be used in place of class_name -- the source
class.
primary_key - Primary key of source model (default: primary key of source
model)
foreign_key - Foreign key of the target model (default: id + '_id')
polymorphic - Set to True if this is a polymorphic association. Class name will
be looked for in the (id + '_type') field. (default: False)
namespace - For polymorphic associations set the full or partial namespace to
prepend to the '_type' field. (default: None)
- Returns:
- None
|
|
Create has collection association
Defines a has association by the name specified by id.
After adding this association you will be able to access it through a
method named the same as the association. This method will return an
instance of Relation representing the query to be run. You can
treat the resulting object as a list of results, and the query will be
executed whenever necessary. This allows you to chain additional scopes
on the query before executing (e.g. person.addresses().primary()).
In addition to keywords listed below this method also accepts all of
the query finder options specified on Relation
- Parameters:
id - name of the association
class_name - Unambiguous name (string) of source class (required).
klass - Can be used in place of class_name -- the source
class.
primary_key - Primary key of target model (default: primary key of target
model)
foreign_key - Foreign key on the source model (default: id + '_id')
as_ - When source is polymorphic this will specify the class name to
use (required when source is polymorphic).
- Returns:
- None
|
|
Create singular has association
Defines a has association by the name specified by id,
and allows access to the association by a method of the same name. A
call to that method will run the query for this association and return
the resulting object, or, if the query has been run previously (or it was
eager loaded), it will return the cached result.
In addition to keywords listed below this method also accepts all of
the query finder options specified on Relation
- Parameters:
id - name of the association
class_name - Unambiguous name (string) of source class (required).
klass - Can be used in place of class_name -- the source
class.
primary_key - Primary key of target model (default: primary key of target
model)
foreign_key - Foreign key on the source model (default: id + '_id')
as_ - When source is polymorphic this will specify the class name to
use (required when source is polymorphic).
- Returns:
- None
|
|
Return a string representation of the object
- Overrides:
object.__repr__
|