On Fri, Oct 5, 2018 at 11:02 AM Victor Reichert <vfr...@gmail.com> wrote:
>
> Hi,
>
> I have a mixin like:
>
> class BasicSqlClass(object):
>
>     @declared_attr
>     def __tablename__(cls):
>         return convert(cls.__name__) + 's
>
>
> The mixin declares the table name and does other stuff.
>
> Hover, there is a class where I wanted to overwrite the mixed-in 
> __tablename__ by declaring the __tablename__ for the class like.
>
> class  SpecialClass(BasicSqlClass, db.Model):
>
>      __tablename__ = 'other_table_name'
>
>
> However, that didn't work.  the mixed-in __tablename__ was still used.

cannot reproduce, see MCVE below

>  I also tried writing a declared attribute for the SpecialClass, but that 
> didn't overwrite the mixin either.

can't reproduce that either, see below

>
> class  SpecialClass(BasicSqlClass, db.Model):
>
>     @declared_attr
>     def __tablename__(cls):
>         return 'other_table_name'
>
>
> I ended up making a special mixin to overwrite the __tablename__.
>
> class OverwriteTableName(object):
>     #I needed to make a class to overwrite the table name
>
>     __tablename__ = 'other_table_name'
>
>
> class  SpecialClass(OverwriteTableName, BasicSqlClass, db.Model):
>
>
>
> The special mixin worked, though I was surprised I was not able to overwrite 
> the mixed-in __tablename__ like a regular inherited attribute.
>
> Any thoughts on this?  If the behavior is expected or intended, If perhaps a 
> warning about this behavior could be added to the documentation that would be 
> great.  I've written a comment below, but I don't know how to propose it's 
> addition to the documentation.

full MCVE, see if this script passes for you and if you can show how it fails:

from sqlalchemy import inspect, create_engine, Column, Integer
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.declarative import declared_attr

Base = declarative_base()


class BasicSqlClass(object):

    @declared_attr
    def __tablename__(cls):
        return cls.__name__ + 's'


class NormalClass(BasicSqlClass, Base):
    id = Column(Integer, primary_key=True)

# mixin works
assert NormalClass.__table__.name == 'NormalClasss'


class SpecialClass(BasicSqlClass, Base):

    __tablename__ = 'other_table_name'
    id = Column(Integer, primary_key=True)

# regular attr overrides
assert SpecialClass.__table__.name == 'other_table_name'


class SpecialClassWDeclared(BasicSqlClass, Base):

    @declared_attr
    def __tablename__(cls):
        return 'other_table_name_declared'
    id = Column(Integer, primary_key=True)


# declared attr overrides
assert SpecialClassWDeclared.__table__.name == 'other_table_name_declared'


e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)

# just to make sure
assert \
    set(inspect(e).get_table_names()) == {
        "NormalClasss", "other_table_name",
        "other_table_name_declared"}




>
> <div class="admonition note">
> <p class="first admonition-title">Note</p>
> <p class="last">
> Mixed-In declared attributes can only be overridden by other mixins.  A 
> declared attribute inherited from a mixed-in class cannot be overridden 
> directly.  For example, a class has a __tablename__ attribute inherited from 
> a mixin where __tablename__ is defined as a declared attribute.  Just adding 
> __tablename__ to the class is insufficient to overwrite the __tablename__ 
> inherited from the mixin for the class.  A second mixin with the 
> __tablename__ attribute must be declared and added to the class with 
> inheritance priority over the mixin.
> </p>
> </div>
>
> I'm thinking it would go at:
>
> https://docs.sqlalchemy.org/en/latest/orm/extensions/declarative/mixins.html
> https://docs.sqlalchemy.org/en/latest/orm/extensions/declarative/api.html#sqlalchemy.ext.declarative.declared_attr
>
>
> Thanks!
>
> ~Victor
>
>
>
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and 
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full 
> description.
> ---
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to