Skip to content

Commit 0ac6def

Browse files
committed
feat: add create_table parameter to control automatic table creation (#10)
1 parent 80e3a11 commit 0ac6def

File tree

3 files changed

+99
-1
lines changed

3 files changed

+99
-1
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,27 @@ adapter = sqlalchemy_adapter.Adapter('sqlite:///test.db', table_name=custom_tabl
6767
e = casbin.Enforcer('path/to/model.conf', adapter)
6868
```
6969

70+
## Prevent Automatic Table Creation
71+
72+
By default, the adapter automatically creates the necessary database tables during initialization. If you want to use the adapter only as an intermediary without automatically creating tables, you can set the `create_table` parameter to `False`:
73+
74+
```python
75+
import sqlalchemy_adapter
76+
import casbin
77+
78+
# Create adapter without automatically creating tables
79+
adapter = sqlalchemy_adapter.Adapter('sqlite:///test.db', create_table=False)
80+
81+
e = casbin.Enforcer('path/to/model.conf', adapter)
82+
```
83+
84+
This is useful when:
85+
- Tables are already created by your database migration system
86+
- You want to manage table creation separately
87+
- You are using the adapter as an intermediary between SQLAlchemy and your system
88+
89+
**Note:** When `create_table=False`, you are responsible for ensuring the required tables exist in the database before using the adapter.
90+
7091

7192
### Getting Help
7293

sqlalchemy_adapter/adapter.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ def __init__(
8080
db_class=None,
8181
table_name="casbin_rule",
8282
filtered=False,
83+
create_table=True,
8384
):
8485
if isinstance(engine, str):
8586
self._engine = create_engine(engine)
@@ -107,7 +108,8 @@ def __init__(
107108
self._db_class = db_class
108109
self.session_local = sessionmaker(bind=self._engine)
109110

110-
metadata.create_all(self._engine)
111+
if create_table:
112+
metadata.create_all(self._engine)
111113
self._filtered = filtered
112114

113115
@contextmanager

tests/test_adapter.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,3 +409,78 @@ def test_update_filtered_policies(self):
409409

410410
e.update_filtered_policies([["bob", "data2", "read"]], 0, "bob")
411411
self.assertTrue(e.enforce("bob", "data2", "read"))
412+
413+
def test_create_table_false(self):
414+
"""Test that tables are not created when create_table=False"""
415+
from sqlalchemy import inspect
416+
417+
engine = create_engine("sqlite://")
418+
419+
# Create adapter with create_table=False
420+
adapter = Adapter(engine, create_table=False)
421+
422+
# Verify that the table was NOT created
423+
inspector = inspect(engine)
424+
tables = inspector.get_table_names()
425+
self.assertEqual(
426+
len(tables), 0, "No tables should be created when create_table=False"
427+
)
428+
429+
def test_create_table_true_default(self):
430+
"""Test that tables are created by default (backward compatibility)"""
431+
from sqlalchemy import inspect
432+
433+
engine = create_engine("sqlite://")
434+
435+
# Create adapter without specifying create_table (should default to True)
436+
adapter = Adapter(engine)
437+
438+
# Verify that the table WAS created
439+
inspector = inspect(engine)
440+
tables = inspector.get_table_names()
441+
self.assertIn("casbin_rule", tables, "Table should be created by default")
442+
443+
def test_create_table_custom_table_name(self):
444+
"""Test that custom table name is not created when create_table=False"""
445+
from sqlalchemy import inspect
446+
447+
engine = create_engine("sqlite://")
448+
table_name = "my_custom_table"
449+
450+
# Create adapter with custom table name and create_table=False
451+
adapter = Adapter(engine, table_name=table_name, create_table=False)
452+
453+
# Verify that the table was NOT created
454+
inspector = inspect(engine)
455+
tables = inspector.get_table_names()
456+
self.assertEqual(
457+
len(tables), 0, "No tables should be created when create_table=False"
458+
)
459+
460+
def test_create_table_custom_db_class(self):
461+
"""Test that custom db_class table is not created when create_table=False"""
462+
from sqlalchemy import inspect
463+
464+
class CustomRule(Base):
465+
__tablename__ = "custom_rule_table"
466+
467+
id = Column(Integer, primary_key=True)
468+
ptype = Column(String(255))
469+
v0 = Column(String(255))
470+
v1 = Column(String(255))
471+
v2 = Column(String(255))
472+
v3 = Column(String(255))
473+
v4 = Column(String(255))
474+
v5 = Column(String(255))
475+
476+
engine = create_engine("sqlite://")
477+
478+
# Create adapter with custom db_class and create_table=False
479+
adapter = Adapter(engine, db_class=CustomRule, create_table=False)
480+
481+
# Verify that the table was NOT created
482+
inspector = inspect(engine)
483+
tables = inspector.get_table_names()
484+
self.assertEqual(
485+
len(tables), 0, "No tables should be created when create_table=False"
486+
)

0 commit comments

Comments
 (0)