dgilland / sqlservice

The missing SQLAlchemy ORM interface.
https://sqlservice.readthedocs.io
MIT License
179 stars 9 forks source link

Ability to pass in metadata #1

Closed ohlookemus closed 8 years ago

ohlookemus commented 8 years ago

This might be me just not reading through the API reference and sourcecode, but I noticed there's no way to pass in metadata like Alchy before.

Alchy:

meta = MetaData(naming_convention={
    "ix": 'ix_%(column_0_label)s',
    "uq": "uk_%(table_name)s_%(column_0_name)s",
    "ck": "ck_%(constraint_name)s",
    "fk": "fk_%(column_0_name)s_%(referred_table_name)s",
    "pk": "pk_%(table_name)s"
}, schema='enterprise')

class BaseClass(ModelBase):
    @declared_attr
    def created_by(cls):
        return sa.Column(sa.SmallInteger, sa.ForeignKey('user_id'))

    @declared_attr
    def created_ts(cls):
        return sa.Column(sa.DateTime(timezone=False), nullable=False,
                         default=datetime.datetime.utcnow,
                         server_default=sa.func.now())

    @declared_attr
    def modified_by(cls):
        return sa.Column(sa.SmallInteger, sa.ForeignKey('user_id'))

    @declared_attr
    def modified_ts(cls):
        return sa.Column(sa.DateTime(timezone=False),
                         onupdate=datetime.datetime.utcnow,
                         server_onupdate=sa.func.now())

Model = make_declarative_base(Base=BaseClass, metadata=meta)

In sqlservice:

def declarative_base(cls=ModelBase):
    """Decorator that converts a normal class into a SQLAlchemy declarative
    base class.
    """
    options = {
        'cls': cls,
        'name': cls.__name__
    }

    if hasattr(cls, '__init__'):
        options['constructor'] = cls.__init__

    if hasattr(cls, 'Meta'):
        options['metaclass'] = cls.Meta

    return declarative.declarative_base(**options)

I think an easy solution (which I could open a PR for) is to just add metadata to the options dict?

dgilland commented 8 years ago

Metadata support is missing as you noticed.

Likely what should change is that sqlservice's declarative_base should accept metaclass and metadata arguments (defaults as None). If they are None, then cls.Meta and cls.metadata (possibly in the future changing cls.Meta to cls.metaclass) would be used if they are defined.

So basically someone could define metaclass/metadata at the class level and have it used in declarative_base or one could define them independent of the base class and instad pass the values explicitly.

dgilland commented 8 years ago

This feature has been released in v0.5.0: https://pypi.python.org/pypi/sqlservice/0.5.0

ohlookemus commented 8 years ago

Thanks!