Search code examples
sqlalchemyflask-sqlalchemy

SQLAlchemy cannot use `__table_args__` to set schema related configuration and index at the same time?


Here is my base class for Model:

@declarative_mixin
class FixtureMixin:
    __table_args__ = {
        "mysql_engine": "InnoDB",
        "mysql_charset": "utf8",
        "extend_existing": True,
    }
    pass

For subclasses, I want to be able to configure the index in __table_args__ while retaining the public configuration, like this:

class TestTable(db.Model, FixtureMixin):
    __tablename__ = "test_table"

    __table_args__ = FixtureMixin.__table_args__.copy()
    __table_args__.update({
        "schema": "test",
        "comment": "xxx",
        "mysql_indexes": [Index('unique_org_test_key', "name", "org_id", unique=True)]
    })
    pass

However, when I create_all, it does not work as expected. What should I do if I want to achieve the expected effect?


Solution

  • Combine parameters and change the way parameters are passed, just like:

    class TestTable(db.Model, FixtureMixin):
        __tablename__ = "test_table"
        __table_args__ = (
            db.UniqueConstraint("name", name="unique_org_test_key"),
            dict(
                **FixtureMixin.__table_args__,
                schema="test",
                comment="xxx"
            )
        )
    

    or:

    class TestTable(db.Model, FixtureMixin):
        __tablename__ = "test_table"
    
        @declared_attr
        def __table_args__(cls):
            table_args = FixtureMixin.__table_args__.copy()
            table_args.update(
                schema="test",
                comment="xxx",
            )
            table_args = (
                db.Index('unique_org_test_key', 'name'),
                table_args,
            )
            return table_args