Orator 0.8 is now out. This version brings several improvements, notably for global scopes, and fixes.
For the full list of changes, see the CHANGELOG
ORM
Global scopes improvements
Global scopes are now easier to use. Global scopes now only require the apply()
method and can be used directly
without the need to create a mixin. Also a simple function can be used as a global scope.
Using a scope directly
from orator import Scope
class ActiveScope(Scope):
def apply(self, builder, model):
return builder.where('active', 1)
Using a callable
class User(Model):
@classmethod
def _boot(cls):
cls.add_global_scope('active_scope', lambda query: query.where('active', 1))
cls.add_global_scope(lambda query: query.order_by('name'))
super(User, cls)._boot()
A @scope
decorator to define query scopes
In previous versions of Orator a query scope was defined by defining a method prefixed
by scope_
:
class User(Model):
def scope_popular(self, query):
return query.where('votes', '>', 100)
def scope_of_type(self, query, type):
return query.where_type(type)
users = User.popular().of_type('member').get()
Now, you can use the @scope
decorator:
from orator.orm import scope
class User(Model):
@scope
def popular(self, query):
return query.where('votes', '>', 100)
@scope
def of_type(self, query, type):
return query.where_type(type)
Support for default values
Orator now supports default values on models with the __attributes__
attribute:
class User(Model):
__attributes__ = {
'active': True
}
Support for only one timestamp column on models
Orator now supports maintaining only one timestamp
column, like so:
class User(Model):
__timestamps__ = ['created_at']
Support for extra conditions on relationships
If you want to apply permanent query conditions on your relationships
you can now do so by returning a Builder
instance instead of a Model
subclass.
For example, let's say you want all comments of a user to be ordered by date of creation in descending order:
class User(Model):
@has_many
def comments(self):
return Comment.order_by('created_at', 'desc')
Schema Builder
Support for a use_current()
on timestamps
When defining timestamp columns you can now specify that the default value
should be the current timestamp using the use_current()
method:
with self.schema.table('users') as table:
table.timestamp('created_at').use_current()
You can also pass the use_current
keyword argument to the timestamps()
method:
with self.schema.table('users') as table:
table.timestamps(use_current=True)
Commands
New make:model
command
The make:model
command creates a new Model
class.
# Create a new ./models/user.py file
orator make:model User
# Create a new ./models/user.py file and a migration file
orator make:model User -m
New commands names
Most commands have been renamed to be more consistent:
migrations:install
becomesmigrate:install
.migrations:make
becomesmake:migration
.migrations:refresh
becomesmigrate:refresh
.migrations:reset
becomesmigrate:reset
.migrations:rollback
becomesmigrate:rollback
.migrations:run
becomesmigrate
.seeders:make
becomesmake:seed
.migrations:install
becomesmigrate:install
.
Connection
Support for unicode by default
For MySQL
and PostgreSQL
, the connectors are configured to return unicode
strings.
If you want to use the previous behavior just set the use_unicode
configuration option to False
.
Other improvements and fixes
Fixes
ORM
- Fixes
Model.get_foreign_key()
method - Fixes soft deletes
- Avoid going through __setattr__ method when setting timestamps
Schema Builder
- #33 [SQLite] Renaming or dropping columns loses NULL constraint
- #32 [SQLite] Renaming or dropping columns fails when columns' name is a keyword
- #31 [SQLite] Changing columns loses default column values.
Query Builder
- Fixes query grammar default columns value
Connection
- Fixing
Connection._try_again_if_caused_by_lost_connection()
not being called - Preventing default connection being set to None
- Fixing json type behavior for Postgres
Migrations
- Fixing migration stubs
Improvements
Schema builder
- Improving dbal to support SQLite fully.
- Improving fluents
Query Builder
- #28 Making
where_in()
method accept Collection instances
Connection
- Improves how queries are run in
Connection
class
Collections
- Adds
flatten()
method toCollection
class