From 781779e2ad7ccb9dc1c5840bff298c1eacaa4a7d Mon Sep 17 00:00:00 2001 From: DanCardin Date: Mon, 29 Jan 2024 17:30:36 -0500 Subject: [PATCH] feat: Add Table abstraction to reduce Row related boilerplate. --- docs/source/api.md | 2 +- pyproject.toml | 2 +- .../row/base.py | 48 ++++++++++++++++++- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/docs/source/api.md b/docs/source/api.md index 5f91a56..0ee1381 100644 --- a/docs/source/api.md +++ b/docs/source/api.md @@ -37,7 +37,7 @@ ```{eval-rst} .. autoapimodule:: sqlalchemy_declarative_extensions.row - :members: Row, Rows + :members: Row, Rows, Table ``` ## Alembic diff --git a/pyproject.toml b/pyproject.toml index 848bb92..4042106 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "sqlalchemy-declarative-extensions" -version = "0.6.7" +version = "0.6.8" authors = ["Dan Cardin "] description = "Library to declare additional kinds of objects not natively supported by SQLAlchemy/Alembic." diff --git a/src/sqlalchemy_declarative_extensions/row/base.py b/src/sqlalchemy_declarative_extensions/row/base.py index c2439cb..bf2656f 100644 --- a/src/sqlalchemy_declarative_extensions/row/base.py +++ b/src/sqlalchemy_declarative_extensions/row/base.py @@ -1,7 +1,7 @@ from __future__ import annotations from dataclasses import dataclass, field, replace -from typing import Iterable +from typing import Any, Iterable @dataclass @@ -27,7 +27,12 @@ def are(self, *rows: Row): return replace(self, rows=rows) +@dataclass class Row: + schema: str | None + tablename: str + column_values: dict[str, Any] + def __init__(self, tablename, **column_values): try: schema, table = tablename.split(".", 1) @@ -38,5 +43,44 @@ def __init__(self, tablename, **column_values): self.schema = schema self.tablename = table - self.qualified_name = tablename self.column_values = column_values + + @property + def qualified_name(self): + if self.schema: + return f"{self.schema}.{self.tablename}" + return self.tablename + + +@dataclass +class Table: + """Convenience class for producing multiple rows against the same table. + + Examples: + Rows might be created directly, like so: + + >>> [ + ... Row("users", id=1, name="John", active=True), + ... Row("users", id=2, name="Bob", active=True), + ... ] + [Row(schema=None, tablename='users', column_values={'id': 1, 'name': 'John', 'active': True}), Row(schema=None, tablename='users', column_values={'id': 2, 'name': 'Bob', 'active': True})] + + But use of `Table` can help elide repetition among those rows: + + >>> users = Table("users", active=True) + >>> [ + ... users.row(id=1, name="John"), + ... users.row(id=2, name="Bob"), + ... ] + [Row(schema=None, tablename='users', column_values={'active': True, 'id': 1, 'name': 'John'}), Row(schema=None, tablename='users', column_values={'active': True, 'id': 2, 'name': 'Bob'})] + """ + name: str + column_values: dict[str, Any] + + def __init__(self, name, **column_values): + self.name = name + self.column_values = column_values + + def row(self, **column_values) -> Row: + final_values= {**self.column_values, **column_values} + return Row(self.name, **final_values)