diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 12a5d4f..178f172 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,6 +1,10 @@
 CHANGE LOG
 ==========
 
+0.3.5
+-----
+- Update the sql.Transpiler to collect namedtuples rather than tuples for attr paths
+
 0.3.4
 -----
 - Update tox.ini and clean up linting errors
diff --git a/setup.py b/setup.py
index bbf57bf..bd16f70 100644
--- a/setup.py
+++ b/setup.py
@@ -14,7 +14,7 @@ def long_description():
 
 setup(
     name='scim2-filter-parser',
-    version='0.3.4',
+    version='0.3.5',
     description='A customizable parser/transpiler for SCIM2.0 filters',
     url='https://github.com/15five/scim2-filter-parser',
     maintainer='Paul Logston',
diff --git a/src/scim2_filter_parser/transpilers/sql.py b/src/scim2_filter_parser/transpilers/sql.py
index 6254f1e..2107758 100644
--- a/src/scim2_filter_parser/transpilers/sql.py
+++ b/src/scim2_filter_parser/transpilers/sql.py
@@ -4,9 +4,12 @@ clause based on a SCIM filter.
 """
 import ast
 import string
+import collections
 
 from .. import ast as scim2ast
 
+AttrPath = collections.namedtuple('AttrPath', ['attr_name', 'sub_attr', 'uri'])
+
 
 class Transpiler(ast.NodeTransformer):
     """
@@ -145,7 +148,7 @@ class Transpiler(ast.NodeTransformer):
 
         # Convert attr_name to another value based on map.
         # Otherwise, return None.
-        attr_path_tuple = (attr_name_value, sub_attr_value, uri_value)
+        attr_path_tuple = AttrPath(attr_name_value, sub_attr_value, uri_value)
         self.attr_paths.append(attr_path_tuple)
         return self.attr_map.get(attr_path_tuple)
 

Return NamedTuple rather than tuple.
It would be nice to return a NamedTuple instead of a tuple here: 

https://github.com/15five/scim2-filter-parser/blob/7ddc216f8c3dd1cdb2152944187e8f7f5ee07be2/src/scim2_filter_parser/transpilers/sql.py#L148

This way parts of each path could be accessed by name rather than by index in the tuple.
diff --git a/tests/test_transpiler.py b/tests/test_transpiler.py
index b8e1bb4..280c2d3 100644
--- a/tests/test_transpiler.py
+++ b/tests/test_transpiler.py
@@ -36,6 +36,16 @@ class RFCExamples(TestCase):
         self.assertEqual(expected_sql, sql, query)
         self.assertEqual(expected_params, params, query)
 
+    def test_attr_paths_are_created(self):
+        query = 'userName eq "bjensen"'
+        tokens = self.lexer.tokenize(query)
+        ast = self.parser.parse(tokens)
+        self.transpiler.transpile(ast)
+
+        self.assertEqual(len(self.transpiler.attr_paths), 1)
+        for path in self.transpiler.attr_paths:
+            self.assertTrue(isinstance(path, transpile_sql.AttrPath))
+
     def test_username_eq(self):
         query = 'userName eq "bjensen"'
         sql = "username = {a}"

pip install -e .
parse_log_pytest
pytest
pytest
3.7
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
asgiref==3.7.2
attrs @ file:///croot/attrs_1668696182826/work
certifi @ file:///croot/certifi_1671487769961/work/certifi
Django==3.2.25
flit_core @ file:///opt/conda/conda-bld/flit-core_1644941570762/work/source/flit_core
importlib-metadata @ file:///tmp/build/80754af9/importlib-metadata_1648562407465/work
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
packaging @ file:///croot/packaging_1671697413597/work
pluggy @ file:///tmp/build/80754af9/pluggy_1648042572264/work
py @ file:///opt/conda/conda-bld/py_1644396412707/work
pytest==7.1.2
pytz==2025.2
-e git+https://github.com/15five/scim2-filter-parser.git@3ed1858b492542d0bc9b9e9ab9547641595e28c1#egg=scim2_filter_parser
sly==0.3
sqlparse==0.4.4
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work
typing_extensions @ file:///croot/typing_extensions_1669924550328/work
zipp @ file:///croot/zipp_1672387121353/work

name: scim2-filter-parser
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - attrs=22.1.0=py37h06a4308_0
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - flit-core=3.6.0=pyhd3eb1b0_0
  - importlib-metadata=4.11.3=py37h06a4308_0
  - importlib_metadata=4.11.3=hd3eb1b0_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - packaging=22.0=py37h06a4308_0
  - pip=22.3.1=py37h06a4308_0
  - pluggy=1.0.0=py37h06a4308_1
  - py=1.11.0=pyhd3eb1b0_0
  - pytest=7.1.2=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py37h06a4308_0
  - typing_extensions=4.4.0=py37h06a4308_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zipp=3.11.0=py37h06a4308_0
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - asgiref==3.7.2
      - django==3.2.25
      - pytz==2025.2
      - sly==0.3
      - sqlparse==0.4.4
prefix: /opt/conda/envs/scim2-filter-parser

tests/test_transpiler.py::RFCExamples::test_attr_paths_are_created
tests/test_transpiler.py::RFCExamples::test_emails_type_eq_work_value_contians_or_ims_type_eq_and_value_contians tests/test_transpiler.py::RFCExamples::test_family_name_contains tests/test_transpiler.py::RFCExamples::test_meta_last_modified_ge tests/test_transpiler.py::RFCExamples::test_meta_last_modified_gt tests/test_transpiler.py::RFCExamples::test_meta_last_modified_le tests/test_transpiler.py::RFCExamples::test_meta_last_modified_lt tests/test_transpiler.py::RFCExamples::test_schema_username_startswith tests/test_transpiler.py::RFCExamples::test_schemas_eq tests/test_transpiler.py::RFCExamples::test_title_has_value tests/test_transpiler.py::RFCExamples::test_title_has_value_and_user_type_eq tests/test_transpiler.py::RFCExamples::test_title_has_value_or_user_type_eq tests/test_transpiler.py::RFCExamples::test_user_type_eq_and_email_contains_or_email_contains tests/test_transpiler.py::RFCExamples::test_user_type_eq_and_not_email_type_eq tests/test_transpiler.py::RFCExamples::test_user_type_eq_and_not_email_type_eq_work_and_value_contains tests/test_transpiler.py::RFCExamples::test_user_type_ne_and_not_email_contains_or_email_contains tests/test_transpiler.py::RFCExamples::test_username_eq tests/test_transpiler.py::RFCExamples::test_username_startswith tests/test_transpiler.py::UndefinedAttributes::test_email_type_eq_primary_value_eq_uuid_1 tests/test_transpiler.py::UndefinedAttributes::test_email_type_eq_primary_value_eq_uuid_2 tests/test_transpiler.py::UndefinedAttributes::test_emails_type_eq_work_value_contians_or_ims_type_eq_and_value_contians_1 tests/test_transpiler.py::UndefinedAttributes::test_emails_type_eq_work_value_contians_or_ims_type_eq_and_value_contians_2 tests/test_transpiler.py::UndefinedAttributes::test_emails_type_eq_work_value_contians_or_ims_type_eq_and_value_contians_3 tests/test_transpiler.py::UndefinedAttributes::test_emails_type_eq_work_value_contians_or_ims_type_eq_and_value_contians_4 tests/test_transpiler.py::UndefinedAttributes::test_schemas_eq tests/test_transpiler.py::UndefinedAttributes::test_title_has_value_and_user_type_eq_1 tests/test_transpiler.py::UndefinedAttributes::test_title_has_value_and_user_type_eq_2 tests/test_transpiler.py::UndefinedAttributes::test_user_type_eq_and_email_contains_or_email_contains tests/test_transpiler.py::UndefinedAttributes::test_user_type_eq_and_not_email_type_eq_1 tests/test_transpiler.py::UndefinedAttributes::test_user_type_eq_and_not_email_type_eq_2 tests/test_transpiler.py::UndefinedAttributes::test_user_type_eq_and_not_email_type_eq_work_and_value_contains_1 tests/test_transpiler.py::UndefinedAttributes::test_user_type_eq_and_not_email_type_eq_work_and_value_contains_2 tests/test_transpiler.py::UndefinedAttributes::test_user_type_eq_and_not_email_type_eq_work_and_value_contains_3 tests/test_transpiler.py::UndefinedAttributes::test_user_type_ne_and_not_email_contains_or_email_contains tests/test_transpiler.py::UndefinedAttributes::test_username_eq tests/test_transpiler.py::AzureQueries::test_email_type_eq_primary_value_eq_uuid tests/test_transpiler.py::AzureQueries::test_external_id_from_azure tests/test_transpiler.py::AzureQueries::test_parse_simple_email_filter_with_uuid tests/test_transpiler.py::CommandLine::test_command_line
setup.py CHANGELOG.rst src/scim2_filter_parser/transpilers/sql.py
setup.py CHANGELOG.rst src/scim2_filter_parser/transpilers/sql.py