sqlalchemy-adapter icon indicating copy to clipboard operation
sqlalchemy-adapter copied to clipboard

Using custom db_class alters global state and subsequent uses fail for db_class=None

Open mick-graft opened this issue 1 year ago • 0 comments

See comments in the code below:

import casbin_sqlalchemy_adapter
import sqlalchemy
from sqlalchemy import Column, Integer, String

ENGINE = sqlalchemy.create_engine("foo")

CUSTOM_SCHEMA = "custom_schema"


class Base(sqlalchemy.orm.DeclarativeBase):
    pass


class CustomCasbinRule(Base):
    """Class we use instead of casbin_sqlalchemy_adapter.CasbinRule, so we can set the right metadata."""

    __tablename__ = "casbin_rule_abc"

    metadata = sqlalchemy.MetaData(schema=CUSTOM_SCHEMA)

    id = Column(Integer, primary_key=True)
    ptype = Column(String(255))
    v0 = Column(String(255))
    v1 = Column(String(255))
    v2 = Column(String(255))
    v3 = Column(String(255))
    v4 = Column(String(255))
    v5 = Column(String(255))

    def __str__(self):
        arr = [str(self.ptype)]
        for v in (self.v0, self.v1, self.v2, self.v3, self.v4, self.v5):
            if v is None:
                break
            arr.append(str(v))
        return ", ".join(arr)

    def __repr__(self):
        return f'<CustomCasbinRule {self.id}: "{self}">'


casbin_sqlalchemy_adapter.Adapter(ENGINE, db_class=CustomCasbinRule)

# At this point the `casbin_sqlalchemy_adapter.Base.metadata` is altered, and following code will create
# the table in "custom_schema" as well, which is unexpected and can cause issues.

casbin_sqlalchemy_adapter.Adapter(ENGINE)

mick-graft avatar Jan 10 '25 22:01 mick-graft