gino.declarative module

class gino.declarative.ColumnAttribute(prop_name, column)

Bases: object

The type of the column wrapper attributes on GINO models.

This is the core utility to enable GINO models so that:

  • Accessing a column attribute on a model class returns the column itself

  • Accessing a column attribute on a model instance returns the value for that column

This utility is customizable by defining __attr_factory__ in the model class.

class gino.declarative.InvertDict(*args, **kwargs)

Bases: dict

A custom dict that allows getting keys by values.

Used internally by Model.

invert_get(value, default=None)

Get key by value.

Parameters
  • value – A value in this dict.

  • default – If specified value doesn’t exist, return default.

Returns

The corresponding key if the value is found, or default otherwise.

class gino.declarative.Model

Bases: object

The base class of GINO models.

This is not supposed to be sub-classed directly, declarative_base() should be used instead to generate a base model class with a given MetaData. By defining subclasses of a model, instances of sqlalchemy.schema.Table will be created and added to the bound MetaData. The columns of the Table instance are defined as Column attributes:

from sqlalchemy import MetaData, Column, Integer, String
from gino.declarative import declarative_base

Model = declarative_base()

class User(db.Model):
    __tablename__ = "users"
    id = Column(Integer(), primary_key=True)
    name = Column(String())

The name of the columns are automatically set using the attribute name.

An instance of a model will maintain a memory storage for values of all the defined column attributes. You can access these values by the same attribute name, or update with new values, just like normal Python objects:

u = User()
assert u.name is None

u.name = "daisy"
assert u.name == "daisy"

Note

Accessing column attributes on a model instance will NOT trigger any database operation.

Constraint and Index are also allowed as model class attributes. Their attribute names are not used.

A concrete model class can be used as a replacement of the Table it reflects in SQLAlchemy queries. The model class is also iterable, yielding all the Column instances defined in the model.

Other built-in class attributes:

  • __metadata__

    This is supposed to be set by declarative_base() and used only during subclass construction. Still, this can be treated as a read-only attribute to find out which MetaData this model is bound to.

  • __tablename__

    This is a required attribute to define a concrete model, meaning a sqlalchemy.schema.Table instance will be created, added to the bound MetaData and set to the class attribute __table__. Not defining __tablename__ will result in an abstract model - no table instance will be created, and instances of an abstract model are meaningless.

  • __table__

    This should usually be treated as an auto-generated read-only attribute storing the sqlalchemy.schema.Table instance.

  • __attr_factory__

    An attribute factory that is used to wrap the actual Column instance on the model class, so that the access to the column attributes on model instances is redirected to the in-memory value store. The default factory is ColumnAttribute, can be override.

  • __values__

    The internal in-memory value store as a dict, only available on model instances. Accessing column attributes is equivalent to accessing __values__.

gino.declarative.declarative_base(metadata, model_classes=(<class 'gino.declarative.Model'>, ), name='Model')

Create a base GINO model class for declarative table definition.

Parameters
  • metadata – A MetaData instance to contain the tables.

  • model_classes – Base class(es) of the base model class to be created. Default: Model.

  • name – The class name of the base model class to be created. Default: Model.

Returns

A new base model class.

gino.declarative.declared_attr(m=None, *, with_table=False)

Mark a class-level method as a factory of attribute.

This is intended to be used as decorators on class-level methods of a Model class. When initializing the class as well as its subclasses, the decorated factory method will be called for each class, the returned result will be set on the class in place of the factory method under the same name.

@declared_attr is implemented differently than declared_attr of SQLAlchemy, but they are both more often used on mixins to dynamically declare indices or constraints (also works for column and __table_args__, or even normal class attributes):

class TrackedMixin:
    created = db.Column(db.DateTime(timezone=True))

    @db.declared_attr
    def unique_id(cls):
        return db.Column(db.Integer())

    @db.declared_attr
    def unique_constraint(cls):
        return db.UniqueConstraint('unique_id')

    @db.declared_attr
    def poly(cls):
        if cls.__name__ == 'Thing':
            return db.Column(db.Unicode())

    @db.declared_attr
    def __table_args__(cls):
        if cls.__name__ == 'Thing':
            return db.UniqueConstraint('poly'),

Note

This doesn’t work if the model already had a __table__.

Changed in version 1.1: Added with_table parameter which works after the __table__ is created:

class User(db.Model):
    __tablename__ = "users"

    ...

    @db.declared_attr(with_table=True)
    def table_name(cls):
        # this is called only once when defining the class
        return cls.__table__.name

assert User.table_name == "users"