Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,27 @@ adapter = sqlalchemy_adapter.Adapter('sqlite:///test.db', table_name=custom_tabl
e = casbin.Enforcer('path/to/model.conf', adapter)
```

## Prevent Automatic Table Creation

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`:

```python
import sqlalchemy_adapter
import casbin

# Create adapter without automatically creating tables
adapter = sqlalchemy_adapter.Adapter('sqlite:///test.db', create_table=False)

e = casbin.Enforcer('path/to/model.conf', adapter)
```

This is useful when:
- Tables are already created by your database migration system
- You want to manage table creation separately
- You are using the adapter as an intermediary between SQLAlchemy and your system

**Note:** When `create_table=False`, you are responsible for ensuring the required tables exist in the database before using the adapter.


### Getting Help

Expand Down
4 changes: 3 additions & 1 deletion sqlalchemy_adapter/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ def __init__(
db_class=None,
table_name="casbin_rule",
filtered=False,
create_table=True,
):
if isinstance(engine, str):
self._engine = create_engine(engine)
Expand Down Expand Up @@ -107,7 +108,8 @@ def __init__(
self._db_class = db_class
self.session_local = sessionmaker(bind=self._engine)

metadata.create_all(self._engine)
if create_table:
metadata.create_all(self._engine)
self._filtered = filtered

@contextmanager
Expand Down
75 changes: 75 additions & 0 deletions tests/test_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,3 +409,78 @@ def test_update_filtered_policies(self):

e.update_filtered_policies([["bob", "data2", "read"]], 0, "bob")
self.assertTrue(e.enforce("bob", "data2", "read"))

def test_create_table_false(self):
"""Test that tables are not created when create_table=False"""
from sqlalchemy import inspect

engine = create_engine("sqlite://")

# Create adapter with create_table=False
adapter = Adapter(engine, create_table=False)

# Verify that the table was NOT created
inspector = inspect(engine)
tables = inspector.get_table_names()
self.assertEqual(
len(tables), 0, "No tables should be created when create_table=False"
)

def test_create_table_true_default(self):
"""Test that tables are created by default (backward compatibility)"""
from sqlalchemy import inspect

engine = create_engine("sqlite://")

# Create adapter without specifying create_table (should default to True)
adapter = Adapter(engine)

# Verify that the table WAS created
inspector = inspect(engine)
tables = inspector.get_table_names()
self.assertIn("casbin_rule", tables, "Table should be created by default")

def test_create_table_custom_table_name(self):
"""Test that custom table name is not created when create_table=False"""
from sqlalchemy import inspect

engine = create_engine("sqlite://")
table_name = "my_custom_table"

# Create adapter with custom table name and create_table=False
adapter = Adapter(engine, table_name=table_name, create_table=False)

# Verify that the table was NOT created
inspector = inspect(engine)
tables = inspector.get_table_names()
self.assertEqual(
len(tables), 0, "No tables should be created when create_table=False"
)

def test_create_table_custom_db_class(self):
"""Test that custom db_class table is not created when create_table=False"""
from sqlalchemy import inspect

class CustomRule(Base):
__tablename__ = "custom_rule_table"

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))

engine = create_engine("sqlite://")

# Create adapter with custom db_class and create_table=False
adapter = Adapter(engine, db_class=CustomRule, create_table=False)

# Verify that the table was NOT created
inspector = inspect(engine)
tables = inspector.get_table_names()
self.assertEqual(
len(tables), 0, "No tables should be created when create_table=False"
)