Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AttributeError: 'CrateTypeCompiler' object has no attribute 'visit_JSONPATH' #189

Open
amotl opened this issue Dec 14, 2024 · 1 comment

Comments

@amotl
Copy link
Member

amotl commented Dec 14, 2024

Problem

When deriving a CrateDB adapter for LangChain from langchain-postgres, we are observing this error when invoking a test case.

pytest -vvv -k "test_cratedb_with_metadata_filters_2 and filter10"
self = JSONPATH(), visitor = <sqlalchemy_cratedb.compiler.CrateTypeCompiler object at 0x10e44c290>
kw = {'ambiguous_table_name_map': {}, 'from_linter': None, 'identifier_preparer': <sqlalchemy_cratedb.compiler.CrateIdentifierPreparer object at 0x10e44c350>, 'type_expression': <sqlalchemy.sql.elements.TypeClause object at 0x10d0f6240>, ...}

    def _compiler_dispatch(
        self: Visitable, visitor: Any, **kw: Any
    ) -> str:
        """Look for an attribute named "visit_<visit_name>" on the
        visitor, and call it with the same kw params.

        """
        try:
>           meth = getter(visitor)
E           AttributeError: 'CrateTypeCompiler' object has no attribute 'visit_JSONPATH'

.venv/lib/python3.12/site-packages/sqlalchemy/sql/visitors.py:137: AttributeError
@amotl
Copy link
Member Author

amotl commented Dec 14, 2024

JSONPath in PostgreSQL is out of reach of CrateDB.

Converting a search constraint into an SQLAlchemy filter expression is located at PGVector._handle_field_filter, and looks like this:

elif operator == "$between":
    # Use AND with two comparisons
    low, high = filter_value

    lower_bound = func.jsonb_path_match(
        self.EmbeddingStore.cmetadata,
        cast(f"$.{field} >= $value", JSONPATH),
        cast({"value": low}, JSONB),
    )
    upper_bound = func.jsonb_path_match(
        self.EmbeddingStore.cmetadata,
        cast(f"$.{field} <= $value", JSONPATH),
        cast({"value": high}, JSONB),
    )
    return sqlalchemy.and_(lower_bound, upper_bound)

It would be sweet to provide an alternative handler, to convert that into SQL instead, how the previous one might have been working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant