Skip to content

Commit 7611a1d

Browse files
authored
Merge pull request #29 from bdowning/updates
Prepended
2 parents bfbe5cb + e6ba07d commit 7611a1d

5 files changed

Lines changed: 39 additions & 4 deletions

File tree

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.4.0-alpha-11
2+
current_version = 0.4.0-alpha-12
33
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(-(?P<release>.*)-(?P<build>\d+))?
44
serialize =
55
{major}.{minor}.{patch}-{release}-{build}

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ dependencies = [
88
"typing-extensions",
99
]
1010
name = "sql-athame"
11-
version = "0.4.0-alpha-11"
11+
version = "0.4.0-alpha-12"
1212
description = "Python tool for slicing and dicing SQL"
1313
readme = "README.md"
1414

sql_athame/dataclasses.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,21 @@ def field_names(cls, *, exclude: FieldNamesSet = ()) -> list[str]:
230230

231231
@classmethod
232232
def field_names_sql(
233-
cls, *, prefix: Optional[str] = None, exclude: FieldNamesSet = ()
233+
cls,
234+
*,
235+
prefix: Optional[str] = None,
236+
exclude: FieldNamesSet = (),
237+
as_prepended: Optional[str] = None,
234238
) -> list[Fragment]:
239+
if as_prepended:
240+
return [
241+
sql(
242+
"{} AS {}",
243+
sql.identifier(f, prefix=prefix),
244+
sql.identifier(f"{as_prepended}{f}"),
245+
)
246+
for f in cls.field_names(exclude=exclude)
247+
]
235248
return [
236249
sql.identifier(f, prefix=prefix) for f in cls.field_names(exclude=exclude)
237250
]
@@ -300,6 +313,16 @@ def from_mapping(cls: type[T], mapping: Mapping[str, Any], /) -> T:
300313
cls.from_mapping = from_mapping_fn # type: ignore
301314
return from_mapping_fn(mapping)
302315

316+
@classmethod
317+
def from_prepended_mapping(
318+
cls: type[T], mapping: Mapping[str, Any], prepend: str
319+
) -> T:
320+
filtered_dict: dict[str, Any] = {}
321+
for k, v in mapping.items():
322+
if k.startswith(prepend):
323+
filtered_dict[k[len(prepend) :]] = v
324+
return cls.from_mapping(filtered_dict)
325+
303326
@classmethod
304327
def ensure_model(cls: type[T], row: Union[T, Mapping[str, Any]]) -> T:
305328
if isinstance(row, cls):

tests/test_dataclasses.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ class Test(ModelBase, table_name="table"):
7171
sql(",").join(t.field_values_sql()),
7272
).query() == ('INSERT INTO table ("foo","bar") VALUES ($1,$2)', [42, "hi"])
7373

74+
assert list(
75+
sql(
76+
"SELECT {fields} FROM {tbl}",
77+
fields=sql.list(Test.field_names_sql(as_prepended="p_")),
78+
tbl=Test.table_name_sql(),
79+
)
80+
) == ['SELECT "foo" AS "p_foo", "bar" AS "p_bar" FROM "table"']
81+
7482

7583
def test_modelclass_implicit_types():
7684
@dataclass
@@ -202,3 +210,7 @@ class Test(ModelBase, table_name="table"):
202210
assert Test.from_mapping({"foo": "FOO", "bar": "BAR"}) == Test("foo", "BAR")
203211
# make sure the monkey patching didn't screw things up
204212
assert Test.from_mapping({"foo": "FOO", "bar": "BAR"}) == Test("foo", "BAR")
213+
214+
assert Test.from_prepended_mapping(
215+
{"p_foo": "FOO", "p_bar": "BAR", "foo": "not foo", "other": "other"}, "p_"
216+
) == Test("foo", "BAR")

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)