Skip to content

Commit 6bea106

Browse files
committed
feat: fix SQLAlchemy warning from duplicate CasbinRule class names (#12)
1 parent ce553e4 commit 6bea106

File tree

1 file changed

+42
-25
lines changed

1 file changed

+42
-25
lines changed

sqlalchemy_adapter/adapter.py

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ class Base(DeclarativeBase):
1919
pass
2020

2121

22+
# Cache for CasbinRule classes by table name to avoid duplicate class warnings
23+
_casbin_rule_cache = {}
24+
25+
2226
def create_casbin_rule_class(table_name):
2327
"""
2428
Factory function to create a CasbinRule class with a custom table name.
@@ -29,31 +33,44 @@ def create_casbin_rule_class(table_name):
2933
Returns:
3034
db_class (CasbinRule): The CasbinRule class.
3135
"""
32-
33-
class CasbinRule(Base):
34-
__tablename__ = table_name
35-
__table_args__ = {"extend_existing": True}
36-
37-
id = Column(Integer, primary_key=True)
38-
ptype = Column(String(255))
39-
v0 = Column(String(255))
40-
v1 = Column(String(255))
41-
v2 = Column(String(255))
42-
v3 = Column(String(255))
43-
v4 = Column(String(255))
44-
v5 = Column(String(255))
45-
46-
def __str__(self):
47-
arr = [self.ptype]
48-
for v in (self.v0, self.v1, self.v2, self.v3, self.v4, self.v5):
49-
if v is None:
50-
break
51-
arr.append(v)
52-
return ", ".join(arr)
53-
54-
def __repr__(self):
55-
return '<CasbinRule {}: "{}">'.format(self.id, str(self))
56-
36+
# Return cached class if it exists for this table name
37+
if table_name in _casbin_rule_cache:
38+
return _casbin_rule_cache[table_name]
39+
40+
# Create a unique class name based on the table name to avoid SQLAlchemy warnings
41+
# Convert table_name to a valid Python class name
42+
class_name = "CasbinRule_" + "".join(c if c.isalnum() else "_" for c in table_name)
43+
44+
# Dynamically create the class with a unique name
45+
CasbinRule = type(
46+
class_name,
47+
(Base,),
48+
{
49+
"__tablename__": table_name,
50+
"__table_args__": {"extend_existing": True},
51+
"id": Column(Integer, primary_key=True),
52+
"ptype": Column(String(255)),
53+
"v0": Column(String(255)),
54+
"v1": Column(String(255)),
55+
"v2": Column(String(255)),
56+
"v3": Column(String(255)),
57+
"v4": Column(String(255)),
58+
"v5": Column(String(255)),
59+
"__str__": lambda self: ", ".join(
60+
[self.ptype]
61+
+ [
62+
v
63+
for v in (self.v0, self.v1, self.v2, self.v3, self.v4, self.v5)
64+
if v is not None
65+
]
66+
),
67+
"__repr__": lambda self: '<CasbinRule {}: "{}">'.format(self.id, str(self)),
68+
"__module__": "sqlalchemy_adapter.adapter",
69+
},
70+
)
71+
72+
# Cache the class before returning
73+
_casbin_rule_cache[table_name] = CasbinRule
5774
return CasbinRule
5875

5976

0 commit comments

Comments
 (0)