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 becomes migrate:install.
  • migrations:make becomes make:migration.
  • migrations:refresh becomes migrate:refresh.
  • migrations:reset becomes migrate:reset.
  • migrations:rollback becomes migrate:rollback.
  • migrations:run becomes migrate.
  • seeders:make becomes make:seed.
  • migrations:install becomes migrate: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 to Collection class
View Comments