-
-
Notifications
You must be signed in to change notification settings - Fork 338
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3694 from mathesar-foundation/explorations_ld
RPC transition for explorations `list` and `delete`
- Loading branch information
Showing
8 changed files
with
289 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Generated by Django 4.2.11 on 2024-07-16 13:07 | ||
|
||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('mathesar', '0010_alter_tablemetadata_column_order_and_more'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='Explorations', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('created_at', models.DateTimeField(auto_now_add=True)), | ||
('updated_at', models.DateTimeField(auto_now=True)), | ||
('name', models.CharField(max_length=128, unique=True)), | ||
('base_table_oid', models.PositiveBigIntegerField()), | ||
('initial_columns', models.JSONField()), | ||
('transformations', models.JSONField(null=True)), | ||
('display_options', models.JSONField(null=True)), | ||
('display_names', models.JSONField()), | ||
('description', models.CharField(null=True)), | ||
('database', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mathesar.database')), | ||
], | ||
options={ | ||
'abstract': False, | ||
}, | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
""" | ||
Classes and functions exposed to the RPC endpoint for managing explorations. | ||
""" | ||
from typing import Optional, TypedDict | ||
|
||
from modernrpc.core import rpc_method | ||
from modernrpc.auth.basic import http_basic_auth_login_required | ||
|
||
from mathesar.rpc.exceptions.handlers import handle_rpc_exceptions | ||
from mathesar.utils.explorations import get_explorations, delete_exploration | ||
|
||
|
||
class ExplorationInfo(TypedDict): | ||
""" | ||
Information about a Exploration. | ||
Attributes: | ||
id: The Django id of an exploration. | ||
database_id: The Django id of the database containing the exploration. | ||
name: The name of the exploration. | ||
base_table_oid: The OID of the base table of the exploration on the database. | ||
initial_columns: A list describing the columns to be included in the exploration. | ||
transformations: A list describing the transformations to be made on the included columns. | ||
display_options: A list desrcibing metadata for the columns in the explorations. | ||
display_names: A map between the actual column names on the database and the alias to be displayed(if any). | ||
description: The description of the exploration. | ||
""" | ||
id: int | ||
database_id: int | ||
name: str | ||
base_table_oid: int | ||
initial_columns: list | ||
transformations: Optional[list] | ||
display_options: Optional[list] | ||
display_names: Optional[dict] | ||
description: Optional[str] | ||
|
||
@classmethod | ||
def from_model(cls, model): | ||
return cls( | ||
id=model.id, | ||
database_id=model.database.id, | ||
name=model.name, | ||
base_table_oid=model.base_table_oid, | ||
initial_columns=model.initial_columns, | ||
transformations=model.transformations, | ||
display_options=model.display_options, | ||
display_names=model.display_names, | ||
description=model.description, | ||
) | ||
|
||
|
||
@rpc_method(name="explorations.list") | ||
@http_basic_auth_login_required | ||
@handle_rpc_exceptions | ||
def list_(*, database_id: int, **kwargs) -> list[ExplorationInfo]: | ||
""" | ||
List information about explorations for a database. Exposed as `list`. | ||
Args: | ||
database_id: The Django id of the database containing the explorations. | ||
Returns: | ||
A list of exploration details. | ||
""" | ||
explorations = get_explorations(database_id) | ||
return [ExplorationInfo.from_model(exploration) for exploration in explorations] | ||
|
||
|
||
@rpc_method(name="explorations.delete") | ||
@http_basic_auth_login_required | ||
@handle_rpc_exceptions | ||
def delete(*, exploration_id: int, **kwargs) -> None: | ||
""" | ||
Delete an exploration. | ||
Args: | ||
exploration_id: The Django id of the exploration to delete. | ||
""" | ||
delete_exploration(exploration_id) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
""" | ||
This file tests the explorations RPC functions. | ||
Fixtures: | ||
rf(pytest-django): Provides mocked `Request` objects. | ||
monkeypatch(pytest): Lets you monkeypatch an object for testing. | ||
""" | ||
from mathesar.rpc import explorations | ||
from mathesar.models.users import User | ||
from mathesar.models.base import Database, Explorations | ||
|
||
|
||
def test_explorations_list(rf, monkeypatch): | ||
request = rf.post('/api/rpc/v0', data={}) | ||
request.user = User(username='alice', password='pass1234') | ||
database_id = 11 | ||
|
||
def mock_exploration_info(_database_id): | ||
if _database_id != database_id: | ||
raise AssertionError('incorrect parameters passed') | ||
return [ | ||
Explorations( | ||
id=2, | ||
database=Database(id=1), | ||
name='page count', | ||
base_table_oid=12375, | ||
initial_columns=[ | ||
{'id': 51586, 'alias': 'Items_Acquisition Date'}, | ||
{'id': 51598, 'alias': 'Items_id'}, | ||
{'id': 51572, 'alias': 'Books_Media', 'jp_path': [[51588, 51596]]}, | ||
{'id': 51573, 'alias': 'Books_Page Count', 'jp_path': [[51588, 51596]]} | ||
], | ||
transformations=[ | ||
{'spec': {'greater': [{'column_name': ['Books_Page Count']}, {'literal': ['50']}]}, 'type': 'filter'} | ||
], | ||
display_options=None, | ||
display_names={ | ||
'Items_id': 'Items_id', | ||
'Items_Book': 'Items_Book', | ||
'Books_Media': 'Books_Media', | ||
'Items_Book_1': 'Items_Book_1', | ||
'Books_Page Count': 'Books_Page Count', | ||
'Items_Acquisition Date': 'Items_Acquisition Date' | ||
}, | ||
description=None | ||
), | ||
Explorations( | ||
id=3, | ||
database=Database(id=1), | ||
name='ISBN', | ||
base_table_oid=12356, | ||
initial_columns=[ | ||
{'id': 51594, 'alias': 'Publishers_Name'}, | ||
{'id': 51575, 'alias': 'Books_ISBN', 'jp_path': [[51593, 51579]]} | ||
], | ||
transformations=[ | ||
{ | ||
'spec': { | ||
'base_grouping_column': 'Publishers_Name', | ||
'grouping_expressions': [ | ||
{'input_alias': 'Publishers_Name', 'output_alias': 'Publishers_Name_grouped'} | ||
], | ||
'aggregation_expressions': [{ | ||
'function': 'distinct_aggregate_to_array', | ||
'input_alias': 'Books_ISBN', | ||
'output_alias': 'Books_ISBN_agged'}] | ||
}, | ||
'type': 'summarize'} | ||
], | ||
display_options=None, | ||
display_names={ | ||
'Books_ISBN': 'Books_ISBN', 'Publishers_Name': 'Publishers_Name' | ||
}, | ||
description=None | ||
) | ||
] | ||
monkeypatch.setattr(explorations, 'get_explorations', mock_exploration_info) | ||
expect_explorations_list = [ | ||
{ | ||
'id': 2, | ||
'database_id': 1, | ||
'name': 'page count', | ||
'base_table_oid': 12375, | ||
'initial_columns': [ | ||
{'id': 51586, 'alias': 'Items_Acquisition Date'}, | ||
{'id': 51598, 'alias': 'Items_id'}, | ||
{'id': 51572, 'alias': 'Books_Media', 'jp_path': [[51588, 51596]]}, | ||
{'id': 51573, 'alias': 'Books_Page Count', 'jp_path': [[51588, 51596]]} | ||
], | ||
'transformations': [ | ||
{'spec': {'greater': [{'column_name': ['Books_Page Count']}, {'literal': ['50']}]}, 'type': 'filter'}], | ||
'display_options': None, | ||
'display_names': { | ||
'Items_id': 'Items_id', | ||
'Items_Book': 'Items_Book', | ||
'Books_Media': 'Books_Media', | ||
'Items_Book_1': 'Items_Book_1', | ||
'Books_Page Count': 'Books_Page Count', | ||
'Items_Acquisition Date': 'Items_Acquisition Date' | ||
}, | ||
'description': None | ||
}, | ||
{ | ||
'id': 3, | ||
'database_id': 1, | ||
'name': 'ISBN', | ||
'base_table_oid': 12356, | ||
'initial_columns': [ | ||
{'id': 51594, 'alias': 'Publishers_Name'}, | ||
{'id': 51575, 'alias': 'Books_ISBN', 'jp_path': [[51593, 51579]]} | ||
], | ||
'transformations': [ | ||
{ | ||
'spec': { | ||
'base_grouping_column': 'Publishers_Name', | ||
'grouping_expressions': [ | ||
{'input_alias': 'Publishers_Name', 'output_alias': 'Publishers_Name_grouped'} | ||
], | ||
'aggregation_expressions': [{ | ||
'function': 'distinct_aggregate_to_array', | ||
'input_alias': 'Books_ISBN', | ||
'output_alias': 'Books_ISBN_agged'}] | ||
}, | ||
'type': 'summarize'} | ||
], | ||
'display_options': None, | ||
'display_names': { | ||
'Books_ISBN': 'Books_ISBN', 'Publishers_Name': 'Publishers_Name' | ||
}, | ||
'description': None | ||
} | ||
] | ||
actual_explorations_list = explorations.list_(database_id=11) | ||
assert actual_explorations_list == expect_explorations_list |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from mathesar.models.base import Explorations | ||
|
||
|
||
def get_explorations(database_id): | ||
return Explorations.objects.filter(database__id=database_id) | ||
|
||
|
||
def delete_exploration(exploration_id): | ||
Explorations.objects.get(id=exploration_id).delete() |