Exemplo n.º 1
0
    def setup_mappers(cls):
        class Descriptions(_base.BasicEntity):
            pass

        class Values(_base.BasicEntity):
            pass

        class CustomValues(_base.BasicEntity, list):
            def __init__(self, *args):
                self.extend(args)

            def __composite_values__(self):
                return self

        desc_values = select(
            [values, descriptions.c.d1, descriptions.c.d2],
            descriptions.c.id == values.c.description_id
        ).alias('descriptions_values') 

        mapper(Descriptions, descriptions, properties={
            'values': relationship(Values, lazy='dynamic'),
            'custom_descriptions': composite(
                                CustomValues,
                                        descriptions.c.d1,
                                        descriptions.c.d2),

        })

        mapper(Values, desc_values, properties={
            'custom_values': composite(CustomValues, 
                                            desc_values.c.v1,
                                            desc_values.c.v2),

        })
Exemplo n.º 2
0
    def test_addr_composite(self):
        flds = "name addr1 addr2 addr3 addr4 email fax phone".split()

        class B(DeclarativeBaseGuid):
            __tablename__ = "b_table"

            def __init__(self, **kwargs):
                for k, v in kwargs.items():
                    setattr(self, k, v)

        l = []
        for fld in flds:
            col = Column(fld, TEXT())
            setattr(B, fld, col)
            l.append(col)
        B.addr = composite(Address, *l)

        s = session()
        a = B(addr1="foo")
        assert a.addr
        a.addr.fax = "baz"
        assert a.addr1 == "foo"
        assert a.addr.addr1 == "foo"
        assert a.addr.fax == "baz"
        s.add(a)
        s.flush()
Exemplo n.º 3
0
    def setup_mappers(cls):
        a, b = cls.tables.a, cls.tables.b

        class A(cls.Comparable):
            pass
        class B(cls.Comparable):
            pass

        class C(cls.Comparable):
            def __init__(self, b1, b2):
                self.b1, self.b2 = b1, b2

            def __composite_values__(self):
                return self.b1, self.b2

            def __eq__(self, other):
                return isinstance(other, C) and \
                    other.b1 == self.b1 and \
                    other.b2 == self.b2


        mapper(A, a, properties={
            'b2':relationship(B),
            'c':composite(C, 'b1', 'b2')
        })
        mapper(B, b)
Exemplo n.º 4
0
class Reporter(Base):
    __tablename__ = "reporters"

    id = Column(Integer(), primary_key=True)
    first_name = Column(String(30), doc="First name")
    last_name = Column(String(30), doc="Last name")
    email = Column(String(), doc="Email")
    favorite_pet_kind = Column(PetKind)
    pets = relationship("Pet",
                        secondary=association_table,
                        backref="reporters")
    articles = relationship("Article", backref="reporter")
    favorite_article = relationship("Article", uselist=False)

    @hybrid_property
    def hybrid_prop(self):
        return self.first_name

    column_prop = column_property(select([func.cast(func.count(id), Integer)]),
                                  doc="Column property")

    composite_prop = composite(CompositeFullName,
                               first_name,
                               last_name,
                               doc="Composite")
Exemplo n.º 5
0
def i18nString(name: str, with_plural: bool=False, **kwargs) -> CompositeProperty:
    """
        Translatable String

        Usage:
          >>> news.topic = ('Deutscher Titel', 'English Topic')
          >>> news.topic.en
          'English Topic'
          >>> template.render('{{ _(news.topic) }}')
          'Deutscher Titel'

        :param name: Prefix of column names
        :param with_plural: Does this Column can have a plural?
                            If true, it will generate for each language a \*_pl column additionally.
        :param kwargs: Additional Parameters passed to Column Instance

        :rtype: :class:`_i18nObject` as :class:`MutableObject(**environment.langs)`
    """

    dwargs = dict(nullable=False, server_default='')
    dwargs.update(kwargs)

    columns = []

    for lang in environment.langs:
        columns.append(Column('%s_%s' % (name, lang), sqUnicode, **dwargs))

    if with_plural:
        for lang in environment.langs:
            columns.append(Column('%s_%s_pl' % (name, lang), sqUnicode, **dwargs))

    cls = composite(with_plural and _i18nPluralizedObject or _i18nObject,
                    *columns,
                    comparator_factory=_i18nObjectComparator)
    return cls
Exemplo n.º 6
0
def prep_database():
    global myengine

    # create engine
    myengine = create_engine('sqlite:///:memory:', echo=False)
    
    # setup table metadata
    metadata = MetaData()
    table_infomatic = Table('infomatic', metadata,
                      Column('id', Integer, primary_key=True),
                      Column('info', Unicode(255)),
                      Column('expectedoffset', Integer),
                      Column('utcdate', DateTime), # for TZAwareDateTime
                      Column('tzname', Unicode), # for TZAwareDateTime
                      Column('tzoffset', Integer)) # for TZAwareDateTime
    
    # setup mappings
    mapper(InfoMatic, table_infomatic, properties={
        'info': table_infomatic.c.info,
        'expectedoffset': table_infomatic.c.expectedoffset,
        'tzawaredate': composite(TZAwareDateTime, 
                                 table_infomatic.c.utcdate, 
                                 table_infomatic.c.tzname,
                                 table_infomatic.c.tzoffset)
    })

    # create all tables
    metadata.create_all(myengine)
Exemplo n.º 7
0
    def setup_mappers(cls):
        a, b = cls.tables.a, cls.tables.b

        class A(cls.Comparable):
            pass
        class B(cls.Comparable):
            pass

        class C(cls.Comparable):
            def __init__(self, b1, b2):
                self.b1, self.b2 = b1, b2

            def __composite_values__(self):
                return self.b1, self.b2

            def __eq__(self, other):
                return isinstance(other, C) and \
                    other.b1 == self.b1 and \
                    other.b2 == self.b2


        mapper(A, a, properties={
            'b2':relationship(B),
            'c':composite(C, 'b1', 'b2')
        })
        mapper(B, b)
Exemplo n.º 8
0
class Vehicle(Base):
    __tablename__ = "vehicles"

    id = Column(types.Integer(),
                Sequence("seq_id"),
                primary_key=True,
                doc="The primary key")
    name = Column(types.String(length=50), doc="The name of the vehicle")
    type = Column(types.Enum(VehicleType, name="vehicle_type"), nullable=False)
    created_at = Column(types.DateTime())
    paint = Column(types.Enum(*COLORS, name="colors"))
    is_used = Column(types.Boolean)

    @property
    def lower_name(self):
        return self.name.lower()

    _engine_cylinders = Column("engine_cylinders", types.BigInteger())
    _engine_displacement = Column(
        "engine_displacement",
        types.Numeric(asdecimal=True, precision=10, scale=2))
    _engine_type = Column("engine_type", types.String(length=25))
    _engine_fuel_type = Column("engine_fuel_type", types.String(length=10))
    engine = orm.composite(Engine, _engine_cylinders, _engine_displacement,
                           _engine_type, _engine_fuel_type)

    _owner_id = Column("owner_id", types.Integer(), ForeignKey(Owner.id))
    owner = orm.relationship(Owner, backref="vehicles")

    def clean_name(self):
        if self.name == "invalid":
            raise ValidationError("invalid vehicle name")
Exemplo n.º 9
0
    def setup_mappers(cls):
        foo = cls.tables.foo

        Point = cls._type_fixture()

        cls.mapper_registry.map_imperatively(
            Foo, foo, properties={"data": composite(Point, foo.c.x, foo.c.y)})
Exemplo n.º 10
0
    def setup_mappers(cls):
        a, b = cls.tables.a, cls.tables.b

        class A(cls.Comparable):
            pass

        class B(cls.Comparable):
            pass

        class C(cls.Comparable):
            def __init__(self, b1, b2):
                self.b1, self.b2 = b1, b2

            def __composite_values__(self):
                return self.b1, self.b2

            def __eq__(self, other):
                return (isinstance(other, C) and other.b1 == self.b1
                        and other.b2 == self.b2)

        mapper(
            A,
            a,
            properties={
                "b2": relationship(B),
                "c": composite(C, "b1", "b2")
            },
        )
        mapper(B, b)
Exemplo n.º 11
0
        class User(decl_base):
            __tablename__ = "user"

            id: Mapped[int] = mapped_column(primary_key=True)
            name: Mapped[str] = mapped_column()

            address: Mapped[Address] = composite(Address, mapped_column())
Exemplo n.º 12
0
    def __init__(cls, classname, bases, dict_):

        new_fields = {}
        for name, attribute in dict_.items():
            if type(attribute) is ControllerData:
                if attribute._writable:
                    requested_colname = "_{0}_requested".format(name)
                    requested_column = Column(requested_colname, *attribute._args, nullable=True, **attribute._kwargs)
                    new_fields[requested_colname] = requested_column

                    actual_colname = "_{0}".format(name)
                    actual_column = Column(actual_colname, *attribute._args, nullable=True, **attribute._kwargs)
                    new_fields[actual_colname] = actual_column

                    composite_colname = "{0}".format(name)
                    new_fields[composite_colname] = composite(ControllerCompositeColumn,
                                                              actual_column,
                                                              requested_column)
                else:
                    new_fields[name] = Column(name, *attribute._args, **attribute._kwargs)

        # Set new fields
        dict_.update(new_fields)
        for new_field_name, new_field in new_fields.items():
            setattr(cls, new_field_name, dict_[new_field_name])

        super(BaseClsMeta, cls).__init__(classname, bases, dict_)
Exemplo n.º 13
0
class Unit(Base):
    __tablename__ = 'units'

    id = Column(Integer, primary_key=True)
    battle_id = Column(ForeignKey('battles.id', name='fk_unit_battle'),
                       nullable=False)
    owner_id = Column(ForeignKey('players.id'))
    type = Column(String, nullable=False)
    xp = Column(Integer, nullable=False)
    level = Column(Integer, nullable=False)
    health = Column(Integer, nullable=False)
    poison_count = Column(Integer)
    did_move = Column(Boolean)
    did_attack = Column(Boolean)
    did_fix = Column(Boolean)
    did_occupy = Column(Boolean)
    x = Column(Integer, nullable=False)
    y = Column(Integer, nullable=False)

    cell = composite(Cell, x, y)

    battle = relationship("Battle",
                          back_populates="units",
                          foreign_keys=[battle_id])
    owner = relationship("Player", back_populates="units")

    # @hybrid_property
    # def cell(self):
    #     return '{0},{1}'.format(self.x, self.y)

    def __repr__(self):
        return 'id={0},x={1},x={2},type={3},owner_id={4}'.format(
            self.id, self.x, self.y, self.type, self.owner_id)
Exemplo n.º 14
0
class Dependency(Base):
    """
    A binary RPM name-epoch-version-release-arch. Kind of a flyweight pattern to avoid
    storing the same NEVRAs multiple times as they consume a lot space.
    Each NEVRA must be unique (there's a unique index defined later).
    Referenced by Build.dependency_keys and Applied/UnappliedChange.prev/curr_dep_id
    """
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    epoch = Column(Integer)
    version = Column(String, nullable=False)
    release = Column(String, nullable=False)
    arch = Column(String, nullable=False)

    # Composite property that can be used for queries that need to compare EVRs
    # RPM's way
    evr = composite(
        RpmEVR,
        epoch,
        version,
        release,
        comparator_factory=RpmEVRComparator,
    )

    nevr = (name, epoch, version, release)
    nevra = (name, epoch, version, release, arch)
    inevra = (id, name, epoch, version, release, arch)
Exemplo n.º 15
0
	def InitMapper( cls, metadata, ObjectType ):
		cls.__table__ = Table( cls.__tablename__, metadata,
				Column('id',	    Integer,     index = True, primary_key = True),
				Column('type_id',	Integer,     ForeignKey( ObjectType.id ), nullable = False),
				Column('parent_id', Integer,     ForeignKey( "%s.id" % cls.__tablename__ ), nullable = True),
				Column('name',      Text,        nullable = False),
				Column('size',      Integer(64), nullable = False, default = 0),
				Column('pos_x',     Integer(64), nullable = False, default = 0),
				Column('pos_y',     Integer(64), nullable = False, default = 0),
				Column('pos_z',     Integer(64), nullable = False, default = 0),
				Column('mtime',	    DateTime,    nullable = False,
					onupdate = func.current_timestamp(), default = func.current_timestamp()))

		cols = cls.__table__.c

		Index('ix_%s_position' % cls.__tablename__, cols.pos_x, cols.pos_y, cols.pos_z)

		mapper( cls, cls.__table__, polymorphic_on = cols.type_id, properties = {
			'type': relation( ObjectType,
				uselist = False,
				backref = backref( 'objects' )),
			# Tree like hierarchy for objects ie. Universe => Solar systems => Planets => etc.
			'children': relation( cls,
				backref = backref( 'parent', remote_side = [ cols.id ] )),
			# Object position in 3D space
			'position': composite( Vector3D, cols.pos_x, cols.pos_y, cols.pos_z ),
			})
 def setUp(self):
     """prep db access"""
     # create engine
     self.db_myengine = create_engine('sqlite:///:memory:', echo=False)
     
     # setup table metadata
     self.db_metadata = MetaData()
     table_infomatic = Table('infomatic', self.db_metadata,
                       Column('id', Integer, primary_key=True),
                       Column('info', Unicode(255)),
                       Column('expectedoffset', Integer),
                       Column('utcdate', DateTime), # for tzawaredate
                       Column('tzname', Unicode), # for tzawaredate
                       Column('tzoffset', Integer)) # for tzawaredate
     
     # setup mappings
     mapper(InfoMatic, table_infomatic, properties={
         'info': table_infomatic.c.info,
         'expectedoffset': table_infomatic.c.expectedoffset,
         'tzawaredate': composite(tzaware_datetime.TZAwareDateTime, 
                                  table_infomatic.c.utcdate, 
                                  table_infomatic.c.tzname,
                                  table_infomatic.c.tzoffset)
     })
     
     # create all tables
     self.db_metadata.create_all(self.db_myengine)
     
     # create session
     self.session = create_session(bind=self.db_myengine, autocommit=True, autoflush=True)
Exemplo n.º 17
0
    def setup_mappers(cls):
        a, b = cls.tables.a, cls.tables.b

        class A(cls.Comparable):
            pass

        class B(cls.Comparable):
            pass

        class C(cls.Comparable):
            def __init__(self, b1, b2):
                self.b1, self.b2 = b1, b2

            def __composite_values__(self):
                return self.b1, self.b2

            def __eq__(self, other):
                return (
                    isinstance(other, C)
                    and other.b1 == self.b1
                    and other.b2 == self.b2
                )

        mapper(
            A,
            a,
            properties={"b2": relationship(B), "c": composite(C, "b1", "b2")},
        )
        mapper(B, b)
Exemplo n.º 18
0
class Vehicle(Base):
    __tablename__ = 'vehicles'

    id = Column(types.Integer(),
                Sequence('seq_id'),
                primary_key=True,
                doc='The primary key')
    name = Column(types.String(), doc='The name of the vehicle')
    type = Column(types.Enum(VehicleType), nullable=False)
    created_at = Column(types.DateTime())
    paint = Column(types.Enum(*COLORS))
    is_used = Column(types.Boolean)

    @property
    def lower_name(self):
        return self.name.lower()

    _engine_cylinders = Column('engine_cylinders', types.BigInteger())
    _engine_displacement = Column(
        'engine_displacement',
        types.Numeric(asdecimal=True, precision=10, scale=2))
    _engine_type = Column('engine_type', types.String(length=25))
    _engine_fuel_type = Column('engine_fuel_type', types.String(length=10))
    engine = orm.composite(Engine, _engine_cylinders, _engine_displacement,
                           _engine_type, _engine_fuel_type)

    _owner_id = Column('owner_id', types.Integer(), ForeignKey(Owner.id))
    owner = orm.relationship(Owner, backref='vehicles')
Exemplo n.º 19
0
class Environment(db.Model):
    model_log.info("Creating environment table")
    id = db.Column(db.Integer, primary_key=True)
    width = db.Column(db.Integer)
    height = db.Column(db.Integer)
    game_objects = db.relationship("GameObject", back_populates="environment")

    dim = composite(Vector, width, height)
Exemplo n.º 20
0
class Vertex(base):
    __tablename__ = "vertices"
    id = Column(Integer, primary_key=True)
    mesh_id = Column(Integer, ForeignKey('meshes.mesh_id'))
    x = Column(Float)
    y = Column(Float)
    z = Column(Float)
    pos = composite(vec3f, x, y, z)
Exemplo n.º 21
0
            class User(decl_base):
                __tablename__ = "user"

                id: Mapped[int] = mapped_column(primary_key=True)
                name: Mapped[str] = mapped_column()

                address: "Address" = composite(  # type: ignore
                    mapped_column(), mapped_column(), mapped_column("zip"))
Exemplo n.º 22
0
    def setup_mappers(cls):
        foo = cls.tables.foo

        Point = cls._type_fixture()

        mapper(Foo, foo, properties={
            'data': composite(Point, foo.c.x, foo.c.y)
        })
Exemplo n.º 23
0
    def setup_mappers(cls):
        foo = cls.tables.foo
        subfoo = cls.tables.subfoo

        Point = cls._type_fixture()

        mapper(Foo, foo, properties={"data": composite(Point, foo.c.x, foo.c.y)})
        mapper(SubFoo, subfoo, inherits=Foo)
Exemplo n.º 24
0
    def setup_mappers(cls):
        foo = cls.tables.foo

        Point = cls._type_fixture()

        mapper(Foo,
               foo,
               properties={'data': composite(Point, foo.c.x, foo.c.y)})
Exemplo n.º 25
0
    def _fixture(self):
        class AB(object):
            def __init__(self, a, b, cd):
                self.a = a
                self.b = b
                self.cd = cd

            @classmethod
            def generate(cls, a, b, c, d):
                return AB(a, b, CD(c, d))

            def __composite_values__(self):
                return (self.a, self.b) + self.cd.__composite_values__()

            def __eq__(self, other):
                return (
                    isinstance(other, AB)
                    and self.a == other.a
                    and self.b == other.b
                    and self.cd == other.cd
                )

            def __ne__(self, other):
                return not self.__eq__(other)

        class CD(object):
            def __init__(self, c, d):
                self.c = c
                self.d = d

            def __composite_values__(self):
                return (self.c, self.d)

            def __eq__(self, other):
                return (
                    isinstance(other, CD)
                    and self.c == other.c
                    and self.d == other.d
                )

            def __ne__(self, other):
                return not self.__eq__(other)

        class Thing(object):
            def __init__(self, ab):
                self.ab = ab

        stuff = self.tables.stuff
        mapper(
            Thing,
            stuff,
            properties={
                "ab": composite(
                    AB.generate, stuff.c.a, stuff.c.b, stuff.c.c, stuff.c.d
                )
            },
        )
        return Thing, AB, CD
Exemplo n.º 26
0
    def _fixture(self):
        class AB:
            def __init__(self, a, b, cd):
                self.a = a
                self.b = b
                self.cd = cd

            @classmethod
            def generate(cls, a, b, c, d):
                return AB(a, b, CD(c, d))

            def __composite_values__(self):
                return (self.a, self.b) + self.cd.__composite_values__()

            def __eq__(self, other):
                return (
                    isinstance(other, AB)
                    and self.a == other.a
                    and self.b == other.b
                    and self.cd == other.cd
                )

            def __ne__(self, other):
                return not self.__eq__(other)

        class CD:
            def __init__(self, c, d):
                self.c = c
                self.d = d

            def __composite_values__(self):
                return (self.c, self.d)

            def __eq__(self, other):
                return (
                    isinstance(other, CD)
                    and self.c == other.c
                    and self.d == other.d
                )

            def __ne__(self, other):
                return not self.__eq__(other)

        class Thing:
            def __init__(self, ab):
                self.ab = ab

        stuff = self.tables.stuff
        self.mapper_registry.map_imperatively(
            Thing,
            stuff,
            properties={
                "ab": composite(
                    AB.generate, stuff.c.a, stuff.c.b, stuff.c.c, stuff.c.d
                )
            },
        )
        return Thing, AB, CD
Exemplo n.º 27
0
        class HasVertex(decl_base):
            __tablename__ = "has_vertex"
            id = Column(Integer, primary_key=True)
            x1 = Column(Integer)
            y1 = Column(Integer)
            x2 = Column(Integer)
            y2 = Column(Integer)

            vertex = composite(Vertex._generate, x1, y1, x2, y2)
Exemplo n.º 28
0
class Eigenvector(base):
    __tablename__ = "eigenvectors"
    eigen_id = Column(Integer, primary_key=True)
    eigen_value = Column(Float)
    x = Column(Float)
    y = Column(Float)
    z = Column(Float)
    mesh_id = Column(Integer, ForeignKey('meshes.mesh_id'))
    direction = composite(vec3f, x, y, z)
Exemplo n.º 29
0
class Terrain(Base):
    __tablename__ = 'terrain'

    battle_id = Column(ForeignKey('battles.id'), primary_key=True)
    x = Column(Integer, primary_key=True)
    y = Column(Integer, primary_key=True)
    type = Column(String)

    cell = composite(Cell, x, y)
Exemplo n.º 30
0
    def setup_mappers(cls):
        values, descriptions = cls.tables.values, cls.tables.descriptions

        class Descriptions(cls.Comparable):
            pass

        class Values(cls.Comparable):
            pass

        class CustomValues(cls.Comparable, list):
            def __init__(self, *args):
                self.extend(args)

            def __composite_values__(self):
                return self

        desc_values = (
            select(values, descriptions.c.d1, descriptions.c.d2)
            .where(
                descriptions.c.id == values.c.description_id,
            )
            .alias("descriptions_values")
        )

        cls.mapper_registry.map_imperatively(
            Descriptions,
            descriptions,
            properties={
                "values": relationship(Values, lazy="dynamic"),
                "custom_descriptions": composite(
                    CustomValues, descriptions.c.d1, descriptions.c.d2
                ),
            },
        )

        cls.mapper_registry.map_imperatively(
            Values,
            desc_values,
            properties={
                "custom_values": composite(
                    CustomValues, desc_values.c.v1, desc_values.c.v2
                )
            },
        )
Exemplo n.º 31
0
class Security(Base):
    __tablename__ = 'securities'

    id = Column(Integer, primary_key=True, name='SECID')
    full = Column(String, name='NAME')
    short = Column(String, name='SHORTNAME')
    latin = Column(String, name='LATNAME')
    issuer = composite(Issuer, full, short, latin)
    isin = Column(String, name='ISIN')
    reg_number = Column(String, name='REGNUMBER')
    issue_size = Column(Integer, name='ISSUESIZE')
    face_value_amount = Column(Float, name='FACEVALUE')
    face_value_unit = Column(String, name='FACEUNIT')

    def update(self, **kwargs):
        for key, value in kwargs.iteritems():
            if hasattr(self, key):
                setattr(self, key, value)

    def remove_attributes(self, *args):
        for attr_name in args:
            if hasattr(self, attr_name):
                setattr(self, attr_name, None)

    @property
    def face_value(self):
        if self.face_value_amount and self.face_value_unit:
            return Money(amount=self.face_value_amount,
                         currency=self.face_value_unit)
        else:
            return None

    @face_value.setter
    def face_value(self, face_value):
        if face_value:
            self.face_value_amount = face_value.amount
            self.face_value_unit = face_value.currency
        else:
            self.face_value_amount = None
            self.face_value_unit = None

    @staticmethod
    def create(_id, issuer, isin, reg_number, issue_size, face_value):
        return Security(id=_id,
                        issuer=issuer,
                        isin=isin,
                        reg_number=reg_number,
                        issue_size=issue_size,
                        face_value=face_value)

    def __repr__(self):
        return 'Security {} of issuer {},' \
               'registration_number {},' \
               'ISIN {},' \
               'issue size {},' \
               'face value {}'.format(self.id, self.issuer, self.reg_number, self.isin, self.issue_size, self.face_value)
Exemplo n.º 32
0
    def setup_mappers(cls):
        foo = cls.tables.foo

        Point = cls._type_fixture()

        # in this case, this is not actually a MutableComposite.
        # so we don't expect it to track changes
        mapper(Foo, foo, properties={
            'data': composite(lambda x, y: Point(x, y), foo.c.x, foo.c.y)
        })
Exemplo n.º 33
0
    def setup_mappers(cls):
        foo = cls.tables.foo

        cls.Point = cls._type_fixture()

        mapper(
            FooWithEq,
            foo,
            properties={"data": composite(cls.Point, foo.c.x, foo.c.y)},
        )
Exemplo n.º 34
0
def MarkdownColumn(name, deferred=False, group=None, **kwargs):
    """
    Create a composite column that autogenerates HTML from Markdown text,
    storing data in db columns named with ``_html`` and ``_text`` prefixes.
    """
    return composite(MarkdownComposite,
        Column(name + '_text', UnicodeText, **kwargs),
        Column(name + '_html', UnicodeText, **kwargs),
        deferred=deferred, group=group or name
        )
Exemplo n.º 35
0
    def setup_mappers(cls):
        foo = cls.tables.foo
        subfoo = cls.tables.subfoo

        Point = cls._type_fixture()

        mapper(Foo,
               foo,
               properties={"data": composite(Point, foo.c.x, foo.c.y)})
        mapper(SubFoo, subfoo, inherits=Foo)
Exemplo n.º 36
0
    def setup_mappers(cls):
        foo = cls.tables.foo

        cls.Point = cls._type_fixture()

        mapper(
            FooWithEq,
            foo,
            properties={"data": composite(cls.Point, foo.c.x, foo.c.y)},
        )
Exemplo n.º 37
0
    def setup_mappers(cls):
        foo = cls.tables.foo

        Point = cls._type_fixture()

        # in this case, this is not actually a MutableComposite.
        # so we don't expect it to track changes
        mapper(Foo, foo, properties={
            'data': composite(lambda x, y: Point(x, y), foo.c.x, foo.c.y)
        })
Exemplo n.º 38
0
def MarkdownColumn(name, deferred=False, group=None, **kwargs):
    """
    Create a composite column that autogenerates HTML from Markdown text,
    storing data in db columns named with ``_html`` and ``_text`` prefixes.
    """
    return composite(MarkdownComposite,
        Column(name + '_text', UnicodeText, **kwargs),
        Column(name + '_html', UnicodeText, **kwargs),
        deferred=deferred, group=group or name
        )
Exemplo n.º 39
0
        class B(ComparableEntity, BaseCls):
            __tablename__ = "b"
            id = Column(ForeignKey(BaseCls.id), primary_key=True)
            thing2 = Column(String(50))
            comp2 = composite(XYThing, Column("x2", Integer),
                              Column("y2", Integer))

            __mapper_args__ = {
                "polymorphic_identity": "b",
                "polymorphic_load": "selectin",
            }
Exemplo n.º 40
0
 def rank_soloq(self):
     return composite(LeagueLeague,
                      self.rank_soloq_tier,
                      self.rank_soloq_rank,
                      self.rank_soloq_points,
                      self.rank_soloq_wins,
                      self.rank_soloq_losses,
                      self.rank_soloq_inactive,
                      self.rank_soloq_hot_streak,
                      self.rank_soloq_fresh_blood,
                      self.rank_soloq_veteran)
Exemplo n.º 41
0
class B(Base):
    """
    A class with a many-to-one relationship to :class:`.C` via its ``c``
    attribute.
    """
    __tablename__ = "table_b"
    id = Column(Integer, primary_key=True)
    foo = Column(Integer)
    c_id = Column('c', Integer, ForeignKey("table_c.id"))
    composite_column = composite(Comp, foo, c_id)
    c = relationship("C")
Exemplo n.º 42
0
def assert_composite_conversion(composite_class, composite_columns, graphene_field,
                                registry, **kwargs):
    composite_column = composite(composite_class, *composite_columns,
                                 doc='Custom Help Text', **kwargs)
    graphene_type = convert_sqlalchemy_composite(composite_column, registry)
    assert isinstance(graphene_type, graphene_field)
    field = graphene_type.Field()
    # SQLAlchemy currently does not persist the doc onto the column, even though
    # the documentation says it does....
    # assert field.description == 'Custom Help Text'
    return field
Exemplo n.º 43
0
class Style(Base):
    """ the styma table """
    __tablename__ = "styma"
    id = Column(Integer, name="styid", primary_key=True)
    alpha = Column(VARCHAR(2), nullable=False, name='alpha')
    digit = Column(Integer, name="digit", nullable=False)
    description = Column(VARCHAR(50), name="description", nullable=False)

    name = composite(StyElement, alpha, digit)

    UniqueConstraint(alpha, digit, name='idx_styno')
Exemplo n.º 44
0
    def setup_mappers(cls):
        values, descriptions = cls.tables.values, cls.tables.descriptions

        class Descriptions(cls.Comparable):
            pass

        class Values(cls.Comparable):
            pass

        class CustomValues(cls.Comparable, list):
            def __init__(self, *args):
                self.extend(args)

            def __composite_values__(self):
                return self

        desc_values = select(
            [values, descriptions.c.d1, descriptions.c.d2],
            descriptions.c.id == values.c.description_id,
        ).alias("descriptions_values")

        mapper(
            Descriptions,
            descriptions,
            properties={
                "values": relationship(Values, lazy="dynamic"),
                "custom_descriptions": composite(
                    CustomValues, descriptions.c.d1, descriptions.c.d2
                ),
            },
        )

        mapper(
            Values,
            desc_values,
            properties={
                "custom_values": composite(
                    CustomValues, desc_values.c.v1, desc_values.c.v2
                )
            },
        )
Exemplo n.º 45
0
    def setup_mappers(cls):
        foo = cls.tables.foo
        subfoo = cls.tables.subfoo

        cls.Point = cls._type_fixture()

        cls.mapper_registry.map_imperatively(
            Foo,
            foo,
            properties={"data": composite(cls.Point, foo.c.x, foo.c.y)},
        )
        cls.mapper_registry.map_imperatively(SubFoo, subfoo, inherits=Foo)
Exemplo n.º 46
0
def test_should_unknown_sqlalchemy_composite_raise_exception():
    class CompositeClass:
        def __init__(self, col1, col2):
            self.col1 = col1
            self.col2 = col2

    re_err = "Don't know how to convert the composite field"
    with pytest.raises(Exception, match=re_err):
        convert_sqlalchemy_composite(
            composite(CompositeFullName, (Column(types.Unicode(50)), Column(types.Unicode(50)))),
            Registry(),
        )
Exemplo n.º 47
0
	def InitMapper( cls, metadata, Parameter, ParameterType ):
		cls.__table__ = Table( cls.__tablename__, metadata,
				Column('param_id',  ForeignKey( Parameter.id ), index = True, primary_key = True ),
				Column('x',         Integer, nullable = False ),
				Column('y',         Integer, nullable = False ),
				Column('z',         Integer, nullable = False ))

		cols = cls.__table__.c

		mapper( cls, cls.__table__, inherits = Parameter, polymorphic_identity = ParameterType,
				exclude_properties = [ 'param_id', 'x', 'y', 'z' ],
				properties = {
						'position': composite( Vector3D, cols.x, cols.y, cols.z ),
					})
Exemplo n.º 48
0
	def InitMapper( cls, metadata, Parameter, ParameterType, Object ):
		cls.__table__ = Table( cls.__tablename__, metadata,
				Column('param_id',  ForeignKey( Parameter.id ), index = True, primary_key = True ),
				Column('x',         Integer, default = 0, nullable = False ),
				Column('y',         Integer, default = 0, nullable = False ),
				Column('z',         Integer, default = 0, nullable = False ),
				Column('parent_id', ForeignKey( Object.id ), nullable = True ))

		cols = cls.__table__.c

		mapper( cls, cls.__table__, inherits = Parameter, polymorphic_identity = ParameterType, properties = {
			'parent' : relation( Object,
				uselist = False ),
			# Object position in 3D space
			'vector': composite( Vector3D, cols.x, cols.y, cols.z ),
			})
Exemplo n.º 49
0
def i18nText(name, **kwargs):
    """
        Translatable Text

        :param name: Prefix of the Column
        :param kwargs: Additional Parameters passed to Column Instance

        :rtype: :class:`_i18nObject` as :class:`MutableObject(**environment.langs)`
    """

    dwargs = dict(nullable=False, server_default='')
    dwargs.update(kwargs)

    columns = []

    for lang in environment.langs:
        columns.append(Column('%s_%s' % (name, lang), sqUnicodeText, **dwargs))

    cls = composite(_i18nObject, *columns, comparator_factory=_i18nObjectComparator)
    return cls
Exemplo n.º 50
0
    def get_mapper_definition(newtable, columnname):
        """Given a Table object, return the Mapper definition for a TZAwareDateTime column"""
        # cycle through columns, find the utcdate, tzname, tzoffset columns
        column_utcdate, column_tzname, column_tzoffset = None, None, None
        new_column_names = {'utcdate': '%s_%s' % (columnname, TZAwareDateTimeColumnNames[0]),
                            'tzname': '%s_%s' % (columnname, TZAwareDateTimeColumnNames[1]),
                            'tzoffset': '%s_%s' % (columnname, TZAwareDateTimeColumnNames[2])
                            }

        for c in newtable.c:
            assert isinstance(c, Column)
            if c.key == new_column_names['utcdate']:
                column_utcdate = c
            elif c.key == new_column_names['tzname']:
                column_tzname = c
            elif c.key == new_column_names['tzoffset']:
                column_tzoffset = c
            if column_utcdate != column_tzname != column_tzoffset != None:
                break

        return composite(TZAwareDateTime,
                         column_utcdate,
                         column_tzname,
                         column_tzoffset)
Exemplo n.º 51
0
    def setMapping(self):
        """
        Map the Metadata classes to the provider database schema
        """
        from sqlalchemy.orm import mapper, relationship, composite, synonym
        from sqlalchemy.sql import select, join

        schema = self.getSchema()

        alt_title_table = schema.tables['ALT_TITLE']
        mapper(AlternativeTitle, alt_title_table)
        
        citation_table = schema.tables['CITATION']
        mapper(ResourceLocator, citation_table, properties={
                'url': citation_table.c.ONLINERES,
                'name': citation_table.c.ONLINERESNAM,
                'description': citation_table.c.ONLINERESDESC,
                'function': citation_table.c.ONLINERESFUNC
                })
        resloc_res_table = schema.tables['RESLOC_RES']

        a_is_resolve_table = schema.tables['A_IS_RESOLVE']
        mapper(AdditionalInformation, citation_table)

        coupled_res_table = schema.tables['COUPLED_RES']
        mapper(CoupledResource, coupled_res_table)

        ctrlvocab_res_table = schema.tables['CTRLVOCAB_RES']
        mapper(Term, ctrlvocab_res_table)

        a_c_resolve_table = schema.tables['A_C_RESOLVE']
        mapper(AccessConstraint, a_c_resolve_table)

        access_use_table = schema.tables['ACCESS_USE']
        o_r_resolve_table = schema.tables['O_R_RESOLVE']
        a_u_resolve_table = schema.tables['A_U_RESOLVE']
        mapper(AccessUse, access_use_table)

        res_party_table = schema.tables['RES_PARTY']
        resparty_res_table = schema.tables['RESPARTY_RES']
        res_party_join = join(res_party_table, resparty_res_table)
        mapper(ResponsibleParty, res_party_join, properties={
            'RESPARTYID': [res_party_table.c.RESPARTYID, resparty_res_table.c.RESPARTYID],
            'ROLEID': resparty_res_table.c.ROLEID,
            'FIRSTNAME': res_party_table.c.FIRSTNAME,
            'SURNAME': res_party_table.c.SURNAME,
            'ORGID': res_party_table.c.ORGID,
            'position': res_party_table.c.POSITIONTITLE,
            'CONTACTID': res_party_table.c.CONTACTID
            })

        parent_id_table = schema.tables['PARENT_ID']
        
        metadata_table = schema.tables['METADATA']
        mapper(ParentId, metadata_table, properties={
                'id': metadata_table.c.IDENTIFIER,
                'codespace': metadata_table.c.CODESPACE
                })
        mapper(Metadata, metadata_table, properties={
            'METADATAID': metadata_table.c.METADATAID,
            'title': metadata_table.c.TITLE,
            'alt_titles': relationship(AlternativeTitle, order_by=AlternativeTitle.ALTTITLE),
            'abstract': metadata_table.c.ABSTRACT,
            'RESTYP_ID': metadata_table.c.RESTYP_ID,
            'resource_locators': relationship(ResourceLocator, secondary=resloc_res_table),
            'unique_id': composite(
                    UniqueId,
                    metadata_table.c.IDENTIFIER,
                    metadata_table.c.CODESPACE),
            'parent_id': relationship(ParentId,
                                      secondary=parent_id_table,
                                      primaryjoin=(metadata_table.c.METADATAID == parent_id_table.c.METADATAID),
                                      secondaryjoin=(metadata_table.c.METADATAID == parent_id_table.c.PARENTID),
                                      uselist=False),
            'coupled_resources': relationship(CoupledResource),
            'terms': relationship(Term),
            'SDSTYP_ID': metadata_table.c.SDSTYP_ID,
            'bounding_box': composite(
                    BoundingBox,
                    metadata_table.c.WEST,
                    metadata_table.c.SOUTH,
                    metadata_table.c.EAST,
                    metadata_table.c.NORTH),
            'vertical_extent': composite(
                    VerticalExtent,
                    metadata_table.c.VERTEXTMIN,
                    metadata_table.c.VERTEXTMAX,
                    metadata_table.c.VERTEXTREF_ID),
            'srs': metadata_table.c.SRSYS_ID,
            'temporal_reference': composite(
                    TemporalReference,
                    metadata_table.c.TEMPEXBGN,
                    metadata_table.c.TEMPEXEND,
                    metadata_table.c.PUBDATE,
                    metadata_table.c.REVDATE,
                    metadata_table.c.CREATED),
            'lineage': metadata_table.c.LINEAGE,
            'spatial_resolutions': composite(
                    SpatialResolution,
                    metadata_table.c.SPARES,
                    select(["NULL"])),
            'ADDITIONAL_INFO': relationship(AdditionalInformation, secondary=a_is_resolve_table),
            'ACCESS_CONSTRAINTS': relationship(AccessConstraint, order_by=AccessConstraint.ISOCODEID),
            'other_access_constraints': relationship(AccessUse, secondary=o_r_resolve_table),
            'use_limitations': relationship(AccessUse, secondary=a_u_resolve_table),
            'RESPARTY': relationship(ResponsibleParty),
            'date': metadata_table.c.MODDATE
        })
Exemplo n.º 52
0
        else:
            return helpers.url_for(controller='/media', action='serve',
                                   slug=self.media.slug, id=self.id,
                                   container=self.container, qualified=qualified)

class MediaFullText(object):
    query = DBSession.query_property()


mapper(MediaFile, media_files)

mapper(MediaFullText, media_fulltext)

_media_mapper = mapper(Media, media, order_by=media.c.title, properties={
    'fulltext': relation(MediaFullText, uselist=False, passive_deletes=True),
    'author': composite(Author, media.c.author_name, media.c.author_email),
    'files': relation(MediaFile, backref='media', order_by=media_files.c.type.asc(), passive_deletes=True),
    'tags': relation(Tag, secondary=media_tags, backref=backref('media', lazy='dynamic', query_class=MediaQuery), collection_class=TagList, passive_deletes=True),
    'categories': relation(Category, secondary=media_categories, backref=backref('media', lazy='dynamic', query_class=MediaQuery), collection_class=CategoryList, passive_deletes=True),

    'comments': dynamic_loader(Comment, backref='media', query_class=CommentQuery, passive_deletes=True),
    'comment_count': column_property(
        sql.select([sql.func.count(comments.c.id)],
                   media.c.id == comments.c.media_id).label('comment_count'),
        deferred=True),
    'comment_count_published': column_property(
        sql.select([sql.func.count(comments.c.id)],
                   sql.and_(comments.c.media_id == media.c.id,
                            comments.c.publishable == True)).label('comment_count_published'),
        deferred=True),
})
Exemplo n.º 53
0
        """Ensure that modifications to the enable_feed prop won't break things.

        You cannot disable the last feed-enable file of a podcast episode.
        """
        if (not on and self.media and self.media.podcast_id
            and len([f for f in self.media.files if f.enable_feed]) == 1):
            raise MediaException, ('Published podcast media requires '
                                   'at least one file be feed-enabled.')
        return on


mapper(MediaFile, media_files)

_media_mapper = mapper(Media, media, properties={
    'status': status_column_property(media.c.status),
    'author': composite(Author, media.c.author_name, media.c.author_email),
    'rating': composite(Rating, media.c.rating_sum, media.c.rating_votes),
    'files': relation(MediaFile, backref='media', order_by=media_files.c.position.asc(), passive_deletes=True),
    'tags': relation(Tag, secondary=media_tags, backref='media', collection_class=TagList),
    'topics': relation(Topic, secondary=media_topics, backref='media', collection_class=TopicList),
    'comments': relation(Comment, secondary=media_comments, backref=backref('media', uselist=False),
        extension=CommentTypeExtension('media'), single_parent=True, passive_deletes=True),
})

# Add comment_count, comment_count_published, ... column properties to Media
_media_mapper.add_properties(_properties_dict_from_labels(
    comment_count_property('comment_count', media_comments),
    comment_count_property('comment_count_published', media_comments, status_where(
        comments.c.status, include='publish', exclude='trash'
    )),
    comment_count_property('comment_count_unreviewed', media_comments, status_where(
Exemplo n.º 54
0
	def __init__(cls, name, bases, dct):
		if "modified" in dct:
			event.listen(cls,'before_update',update_modified)
			
		if "id" not in dct:
			# the inherited class already has an 'id' column, but that ends
			# up being ambiguous and thus won't work
			dct['id'] = cls.id = db.Column(db.Integer, primary_key=True)
		cls._refs = []
		cls.__table_args__ = list(dct.get('__table_args__',[])) # collect indices for foreign-key tables here

		# Now walk through all our (base) classes.
		# This is necessary to collect ObjectRef entries in subclasses
		seen = set()
		_alias = cls._alias

		for ccls in cls.__mro__:
			for k,v in ccls.__dict__.items():
				if k == "_alias":
					# merge _alias content
					for kk,vv in v.items():
						_alias.setdefault(kk,vv)
					continue
				if k.startswith('_'): continue
				if k in seen: continue
				seen.add(k)

				if ObjectRef is not None and isinstance(v,ObjectRef):
					if v.typ is None: ## any table
						from .objtyp import ObjType

						## Create a new composite.
						if v.declared_attr:
							col_typ = declared_attr((lambda k,v: lambda cls: Column(k+'_typ_id',db.Integer, db.ForeignKey(ObjType.id),nullable=v.nullable, doc=v.doc, unique=v.unique))(k,v))
							col_id = declared_attr((lambda k,v: lambda cls: Column(k+'_id',db.Integer, nullable=v.nullable))(k,v))
						else:
							col_typ = db.Column(k+'_typ_id',db.Integer, db.ForeignKey(ObjType.id),nullable=v.nullable, doc=v.doc, unique=v.unique)
							col_id = db.Column(k+'_id',db.Integer, nullable=v.nullable)
						setattr(cls,k+"_typ_id", col_typ)
						setattr(cls,k+"_id", col_id)
						if v.declared_attr:
							setattr(cls,k, declared_attr((lambda col_typ,col_id: lambda cls: composite(ObjectRef, col_typ,col_id, deferred=True))(col_typ,col_id)))
						else:
							setattr(cls,k, composite(ObjRefComposer, col_typ,col_id, deferred=True))
						_refs.append((cls,k))
						cls.__table_args__.append(Index("i_%s_%s"%(name,k),col_typ,col_id))
					else: ## specific table
						rem = {'lazy': v.lazy}
						if v.backref:
							rem['back_populates'] = v.backref
						if isinstance(v.typ,(int,long)):
							v.typ = ObjType.get_mod(v.typ)
							v.typ_id = v.typ.id
						elif isinstance(v.typ,string_types):
							if v.typ == "self":
								col_typ = db.Column(k+'_id',db.Integer, db.ForeignKey(cls.__tablename__+'.id'),nullable=v.nullable, doc=v.doc, unique=v.unique)
								col_ref = db.relationship(cls, remote_side=[cls.id], foreign_keys=(col_typ,), **rem)
								setattr(cls,k+"_id", col_typ)
								setattr(cls,k, col_ref)
								cls._refs.append((cls,k))
								cls.__table_args__.append(Index("i_%s_%s"%(name,k),col_typ))
								if v.backref:
									setattr(cls,v.backref, db.relationship(cls, primaryjoin = col_typ==cls.id, back_populates=k, uselist=not v.unique))
								continue
							else:
								v.typ = ObjType.q.get_by(path=v.typ).mod
								v.typ_id = v.typ.id
						else:
							v.typ_id = v.typ.id
							rem['remote_side'] = v.typ.__name__+'.id'
						if v.declared_attr:
							col_typ = declared_attr((lambda k,v: lambda cls: Column(k+'_id',db.Integer, db.ForeignKey(v.typ_id),nullable=v.nullable, doc=v.doc, unique=v.unique))(k,v))
							col_ref = declared_attr((lambda k,v,r: lambda cls: db.relationship(v.typ, primaryjoin = col_typ==v.typ_id, **r))(k,v,rem))
						else:
							col_typ = db.Column(k+'_id',db.Integer, db.ForeignKey(v.typ_id),nullable=v.nullable, doc=v.doc, unique=v.unique)
							col_ref = db.relationship(v.typ, primaryjoin = col_typ==v.typ_id, **rem)
						setattr(cls,k+"_id", col_typ)
						setattr(cls,k, col_ref)
						v.typ._refs.append((cls,k))
						cls.__table_args__.append(Index("i_%s_%s"%(name,k),col_typ))
						if v.backref:
							if isinstance(v.typ,string_types):
								setattr(v.typ,v.backref, db.relationship(cls, primaryjoin = "%s_id==%s" % (k,v.typ_id), back_populates=k))
							else:
								setattr(v.typ,v.backref, db.relationship(cls, primaryjoin = col_typ==v.typ.id, back_populates=k, uselist=not v.unique))
					
				elif k == 'modified':
					event.listen(cls,'before_update',update_modified)
			
		_tables.append(cls)
		cls_ = cls
		cls.__table_args__ = tuple(cls.__table_args__)
		class serializer(_serialize_object):
			cls = cls_
			clsname = cls_.__module__+'.'+cls_.__name__
		json_adapter(serializer)

		setup_events(cls)

		super(ObjectMeta, cls).__init__(name, bases, dct)
Exemplo n.º 55
0
    query = DBSession.query_property(CommentQuery)

    def __repr__(self):
        return '<Comment: %s subject="%s">' % (self.id, self.subject)

    def __unicode__(self):
        return self.subject

    @property
    def type(self):
        if self.media_id:
            return 'media'
        return None

    def _get_parent(self):
        return self.media or None
    def _set_parent(self, parent):
        self.media = parent
    parent = property(_get_parent, _set_parent, None, """
        The object this Comment belongs to, provided for convenience mostly.
        If the parent has not been eagerloaded, a query is executed automatically.
    """)


mapper(Comment, comments, order_by=comments.c.created_on, properties={
    'author': composite(AuthorWithIP,
        comments.c.author_name,
        comments.c.author_email,
        comments.c.author_ip),
})
Exemplo n.º 56
0
        Return the maximum depth recorded over all dives at this site
        '''
        md = 0
        for dive in self.dives:
            if dive.max_depth > md:
                md = dive.max_depth
        return md
    
    @property
    def rating(self):
        '''
        Return the average rating for dives at this site.  Only considers dives
        which have a non-zero rating.
        '''
        r = 0
        n = 0
        for dive in self.dives:
            if dive.rating:
                r += dive.rating
                n += 1
        return r / n if n > 0 else 0
    
    def __repr__(self):
        return '<DiveSite: %s>' % self.site
    
# Dive Site Mapper
mapper(DiveSite, tables.sites, properties={
    'dives': relationship(Dive, backref=backref('dive_site', lazy='join')),
    'latlng': composite(LatLng, tables.sites.c.lat, tables.sites.c.lon)
})
Exemplo n.º 57
0
    query = DBSession.query_property()

    _thumb_dir = 'podcasts'

    def __repr__(self):
        return '<Podcast: %s>' % self.slug

    @validates('slug')
    def validate_slug(self, key, slug):
        return slugify(slug)


mapper(Podcast, podcasts, order_by=podcasts.c.title, extension=events.MapperObserver(events.Podcast), properties={
    'author': composite(Author,
        podcasts.c.author_name,
        podcasts.c.author_email),
    'media': dynamic_loader(Media, backref='podcast', query_class=MediaQuery, passive_deletes=True),
    'media_count':
        column_property(
            sql.select(
                [sql.func.count(media.c.id)],
                media.c.podcast_id == podcasts.c.id,
            ).label('media_count'),
            deferred=True
        ),
    'media_count_published':
        column_property(
            sql.select(
                [sql.func.count(media.c.id)],
                sql.and_(
Exemplo n.º 58
0
def MarkdownColumn(name, deferred=False, group=None, **kwargs):
    return composite(MarkdownComposite,
        Column(name + '_text', UnicodeText, **kwargs),
        Column(name + '_html', UnicodeText, **kwargs),
        deferred=deferred, group=group or name
        )
Exemplo n.º 59
0
 def address(cls):
     return composite(Address, cls.addr_name, cls.addr_addr1, cls.addr_addr2, cls.addr_addr3, cls.addr_addr4,
                      cls.addr_email, cls.addr_fax, cls.addr_phone)
Exemplo n.º 60
0
    #       so that its other uses throughout the code make more sense.
    _thumb_dir = 'podcasts'

    def __repr__(self):
        return '<Podcast: %r>' % self.slug

    @validates('slug')
    def validate_slug(self, key, slug):
        return slugify(slug)


mapper(Podcast, podcasts, order_by=podcasts.c.title, extension=events.MapperObserver(events.Podcast), properties={
    'author': composite(Author,
        podcasts.c.author_name,
        podcasts.c.author_email,
        doc="""An instance of :class:`mediadrop.model.authors.Author`.
               Although not actually a relation, it is implemented as if it were.
               This was decision was made to make it easier to integrate with
               :class:`mediadrop.model.auth.User` down the road."""),

    'media': dynamic_loader(Media, backref='podcast', query_class=MediaQuery, passive_deletes=True, doc=\
        """A query pre-filtered to media published under this podcast.
        Returns :class:`mediadrop.model.media.MediaQuery`."""),

    'media_count':
        column_property(
            sql.select(
                [sql.func.count(media.c.id)],
                media.c.podcast_id == podcasts.c.id,
            ).label('media_count'),
            deferred=True,