Skip to content

Commit

Permalink
Merge pull request #3672 from mathesar-foundation/tables_metadata_imp…
Browse files Browse the repository at this point in the history
…rovements

Improve tables metadata
  • Loading branch information
seancolsen authored Jul 11, 2024
2 parents dea9210 + 3396114 commit 024c1b5
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 62 deletions.
6 changes: 3 additions & 3 deletions docs/docs/api/rpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ To use an RPC function:
options:
members:
- list_
- patch
- TableMetaData
- SettableTableMetaData
- set_
- TableMetaDataBlob
- TableMetaDataRecord

## Columns

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Generated by Django 4.2.11 on 2024-07-10 18:16

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('mathesar', '0009_add_column_metadata_model'),
]

operations = [
migrations.AlterField(
model_name='tablemetadata',
name='column_order',
field=models.JSONField(null=True),
),
migrations.AlterField(
model_name='tablemetadata',
name='import_verified',
field=models.BooleanField(null=True),
),
migrations.AlterField(
model_name='tablemetadata',
name='record_summary_customized',
field=models.BooleanField(null=True),
),
migrations.AlterField(
model_name='tablemetadata',
name='record_summary_template',
field=models.CharField(max_length=255, null=True),
),
]
8 changes: 4 additions & 4 deletions mathesar/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,10 @@ class Meta:
class TableMetaData(BaseModel):
database = models.ForeignKey('Database', on_delete=models.CASCADE)
table_oid = models.PositiveBigIntegerField()
import_verified = models.BooleanField(default=False)
column_order = models.JSONField(default=list)
record_summary_customized = models.BooleanField(default=False)
record_summary_template = models.CharField(max_length=255, blank=True)
import_verified = models.BooleanField(null=True)
column_order = models.JSONField(null=True)
record_summary_customized = models.BooleanField(null=True)
record_summary_template = models.CharField(max_length=255, null=True)

class Meta:
constraints = [
Expand Down
28 changes: 28 additions & 0 deletions mathesar/rpc/tables/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
from mathesar.rpc.columns import CreatableColumnInfo, SettableColumnInfo, PreviewableColumnInfo
from mathesar.rpc.constraints import CreatableConstraintInfo
from mathesar.rpc.exceptions.handlers import handle_rpc_exceptions
from mathesar.rpc.tables.metadata import TableMetaDataBlob
from mathesar.rpc.utils import connect
from mathesar.utils.tables import get_tables_meta_data


class TableInfo(TypedDict):
Expand Down Expand Up @@ -231,3 +233,29 @@ def get_import_preview(
user = kwargs.get(REQUEST_KEY).user
with connect(database_id, user) as conn:
return get_preview(table_oid, columns, conn, limit)


@rpc_method(name="tables.list_with_metadata")
@http_basic_auth_login_required
@handle_rpc_exceptions
def list_with_metadata(*, schema_oid: int, database_id: int, **kwargs) -> list:
"""
List tables in a schema, along with the metadata associated with each table
Args:
schema_oid: PostgreSQL OID of the schema containing the tables.
database_id: The Django id of the database containing the table.
Returns:
A list of table details.
"""
user = kwargs.get(REQUEST_KEY).user
with connect(database_id, user) as conn:
tables = get_table_info(schema_oid, conn)

metadata_records = get_tables_meta_data(database_id)
metadata_map = {
r.table_oid: TableMetaDataBlob.from_model(r) for r in metadata_records
}

return [table | {"metadata": metadata_map.get(table["oid"])} for table in tables]
41 changes: 23 additions & 18 deletions mathesar/rpc/tables/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
from modernrpc.auth.basic import http_basic_auth_login_required

from mathesar.rpc.exceptions.handlers import handle_rpc_exceptions
from mathesar.utils.tables import get_tables_meta_data, patch_table_meta_data
from mathesar.utils.tables import get_tables_meta_data, set_table_meta_data


class TableMetaData(TypedDict):
class TableMetaDataRecord(TypedDict):
"""
Metadata for a table in a database.
Expand Down Expand Up @@ -46,9 +46,9 @@ def from_model(cls, model):
)


class SettableTableMetaData(TypedDict):
class TableMetaDataBlob(TypedDict):
"""
Settable metadata fields for a table in a database.
The metadata fields which can be set on a table
Attributes:
import_verified: Specifies whether a file has been successfully imported into a table.
Expand All @@ -61,11 +61,20 @@ class SettableTableMetaData(TypedDict):
record_summary_customized: Optional[bool]
record_summary_template: Optional[str]

@classmethod
def from_model(cls, model):
return cls(
import_verified=model.import_verified,
column_order=model.column_order,
record_summary_customized=model.record_summary_customized,
record_summary_template=model.record_summary_template,
)


@rpc_method(name="tables.metadata.list")
@http_basic_auth_login_required
@handle_rpc_exceptions
def list_(*, database_id: int, **kwargs) -> list[TableMetaData]:
def list_(*, database_id: int, **kwargs) -> list[TableMetaDataRecord]:
"""
List metadata associated with tables for a database.
Expand All @@ -77,26 +86,22 @@ def list_(*, database_id: int, **kwargs) -> list[TableMetaData]:
"""
table_meta_data = get_tables_meta_data(database_id)
return [
TableMetaData.from_model(model) for model in table_meta_data
TableMetaDataRecord.from_model(model) for model in table_meta_data
]


@rpc_method(name="tables.metadata.patch")
@rpc_method(name="tables.metadata.set")
@http_basic_auth_login_required
@handle_rpc_exceptions
def patch(
*, table_oid: int, metadata_dict: SettableTableMetaData, database_id: int, **kwargs
) -> TableMetaData:
def set_(
*, table_oid: int, metadata: TableMetaDataBlob, database_id: int, **kwargs
) -> None:
"""
Alter metadata settings associated with a table for a database.
Set metadata for a table.
Args:
table_oid: Identity of the table whose metadata we'll modify.
metadata_dict: The dict describing desired table metadata alterations.
table_oid: The PostgreSQL OID of the table.
metadata: A TableMetaDataBlob object describing desired table metadata to set.
database_id: The Django id of the database containing the table.
Returns:
Altered metadata object.
"""
table_meta_data = patch_table_meta_data(table_oid, metadata_dict, database_id)
return TableMetaData.from_model(table_meta_data)
set_table_meta_data(table_oid, metadata, database_id)
27 changes: 2 additions & 25 deletions mathesar/tests/rpc/tables/test_t_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,39 +29,16 @@ def mock_get_tables_meta_data(_database_id):
monkeypatch.setattr(metadata, "get_tables_meta_data", mock_get_tables_meta_data)

expect_metadata_list = [
metadata.TableMetaData(
metadata.TableMetaDataRecord(
id=1, database_id=database_id, table_oid=1234,
import_verified=True, column_order=[8, 9, 10], record_summary_customized=False,
record_summary_template="{5555}"
),
metadata.TableMetaData(
metadata.TableMetaDataRecord(
id=2, database_id=database_id, table_oid=4567,
import_verified=False, column_order=[], record_summary_customized=True,
record_summary_template="{5512} {1223}"
)
]
actual_metadata_list = metadata.list_(database_id=database_id)
assert actual_metadata_list == expect_metadata_list


def test_tables_meta_data_patch(monkeypatch):
database_id = 2
metadata_dict = {'import_verified': True, 'column_order': [1, 4, 12]}

def mock_patch_tables_meta_data(table_oid, metadata_dict, _database_id):
server_model = Server(id=2, host='example.com', port=5432)
db_model = Database(id=_database_id, name='mymathesardb', server=server_model)
return TableMetaData(
id=1, database=db_model, table_oid=1234,
import_verified=True, column_order=[1, 4, 12], record_summary_customized=False,
record_summary_template="{5555}"
)
monkeypatch.setattr(metadata, "patch_table_meta_data", mock_patch_tables_meta_data)

expect_metadata_object = metadata.TableMetaData(
id=1, database_id=database_id, table_oid=1234,
import_verified=True, column_order=[1, 4, 12], record_summary_customized=False,
record_summary_template="{5555}"
)
actual_metadata_object = metadata.patch(table_oid=1234, metadata_dict=metadata_dict, database_id=2)
assert actual_metadata_object == expect_metadata_object
9 changes: 7 additions & 2 deletions mathesar/tests/rpc/test_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@
"tables.list",
[user_is_authenticated]
),
(
tables.list_with_metadata,
"tables.list_with_metadata",
[user_is_authenticated]
),
(
tables.get,
"tables.get",
Expand Down Expand Up @@ -142,8 +147,8 @@
[user_is_authenticated]
),
(
tables.metadata.patch,
"tables.metadata.patch",
tables.metadata.set_,
"tables.metadata.set",
[user_is_authenticated]
)
]
Expand Down
16 changes: 6 additions & 10 deletions mathesar/utils/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from mathesar.database.base import create_mathesar_engine
from mathesar.imports.base import create_table_from_data_file
from mathesar.models.deprecated import Table
from mathesar.models.base import TableMetaData
from mathesar.models.base import Database, TableMetaData
from mathesar.state.django import reflect_columns_from_tables
from mathesar.state import get_cached_metadata

Expand Down Expand Up @@ -90,13 +90,9 @@ def get_tables_meta_data(database_id):
return TableMetaData.objects.filter(database__id=database_id)


def patch_table_meta_data(table_oid, metadata_dict, database_id):
metadata_model = TableMetaData.objects.get(database__id=database_id, table_oid=table_oid)
alterable_fields = (
'import_verified', 'column_order', 'record_summary_customized', 'record_summary_template'
def set_table_meta_data(table_oid, metadata, database_id):
TableMetaData.objects.update_or_create(
database=Database.objects.get(id=database_id),
table_oid=table_oid,
defaults=metadata,
)
for field, value in metadata_dict.items():
if field in alterable_fields:
setattr(metadata_model, field, value)
metadata_model.save()
return metadata_model

0 comments on commit 024c1b5

Please sign in to comment.