Skip to content

Feature/allow pass configuration for to ts query#4

Open
fullonic wants to merge 13 commits intodevelopfrom
feature/allow-pass-configuration-for-ToTsQuery
Open

Feature/allow pass configuration for to ts query#4
fullonic wants to merge 13 commits intodevelopfrom
feature/allow-pass-configuration-for-ToTsQuery

Conversation

@fullonic
Copy link
Collaborator

@fullonic fullonic commented Jul 2, 2025

Supersede #2. This is version contains the latest version of Tortoise-ORM, v0.25

Description

Updates search-related functions and the SearchCriterion object to receive a new configuration parameter: config_name. By default, we use the PostgreSQL default text search config, pg_catalog.simple.

Motivation and Context

When using PostgreSQL search, the user might need to change the default configuration. This PR makes it possible by allowing the user to specify which config he/she wants to use. For example, using the PostgreSQL extension unaccent, we can now query as:

await City.filter(name__search=ToTsQuery("paris", "public.unaccent"))

Tortoise will generate the below SQL query

'SELECT "id", "name" FROM "cities" WHERE TO_TSVECTOR(\'public.unaccent\',"name") @@ TO_TSQUERY(\'public.unaccent\',\'paris\')'

Because of the current implementation of the __search filter, inside the SearchCriterion.__init__, we extract the config_name from the function in use, in the above example ToTsQuery, to pass it to the ToTsVector function.

How Has This Been Tested?

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added the changelog accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@fullonic fullonic self-assigned this Jul 2, 2025
@fullonic fullonic requested a review from Copilot July 2, 2025 08:05
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Introduces an optional config_name parameter for PostgreSQL full-text search functions and ensures the chosen configuration is propagated in search filters.

  • Adds DEFAULT_TEXT_SEARCH_CONFIG and extends ToTsVector, ToTsQuery, and PlainToTsQuery to accept config_name.
  • Updates SearchCriterion to extract and forward the config_name from the query term.
  • Applies a blanket # type: ignore to the updated SearchCriterion.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
tortoise/contrib/postgres/functions.py Added default config constant and updated search function classes to accept config_name.
tortoise/contrib/postgres/search.py Modified SearchCriterion to pass the extracted config_name into ToTsVector.
Comments suppressed due to low confidence (4)

tortoise/contrib/postgres/functions.py:11

  • [nitpick] The docstring for ToTsVector should be updated to describe the new config_name parameter, its default value, and how it affects the generated SQL.
    def __init__(self, field: Term, config_name: str = DEFAULT_TEXT_SEARCH_CONFIG) -> None:

tortoise/contrib/postgres/functions.py:20

  • [nitpick] The docstring for ToTsQuery should be updated to explain the config_name parameter and its default behavior in the SQL query.
    def __init__(self, field: Term, config_name: str = DEFAULT_TEXT_SEARCH_CONFIG) -> None:

tortoise/contrib/postgres/functions.py:29

  • [nitpick] The docstring for PlainToTsQuery needs an update to include information on the newly added config_name parameter and its effect.
    def __init__(self, field: Term, config_name: str = DEFAULT_TEXT_SEARCH_CONFIG) -> None:

tortoise/contrib/postgres/search.py:15

  • Consider adding unit tests to verify that custom config_name values are correctly propagated through SearchCriterion and reflected in the generated SQL.
        if not isinstance(expr, Function):

Comment on lines 13 to 17
class SearchCriterion(BasicCriterion): # type: ignore
def __init__(self, field: Term, expr: Union[Term, Function]) -> None:
if isinstance(expr, Function):
_expr = expr
else:
_expr = ToTsQuery(expr)
super().__init__(Comp.search, ToTsVector(field), _expr)
if not isinstance(expr, Function):
expr = ToTsQuery(expr)
super().__init__(Comp.search, ToTsVector(config_name=expr.args[0].value, field=field), expr)
Copy link

Copilot AI Jul 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The # type: ignore suppresses all type errors and may hide real issues; consider resolving the underlying type mismatch or narrowing the ignore to a specific expression instead of a blanket ignore.

Copilot uses AI. Check for mistakes.
super().__init__(Comp.search, ToTsVector(field), _expr)
if not isinstance(expr, Function):
expr = ToTsQuery(expr)
super().__init__(Comp.search, ToTsVector(config_name=expr.args[0].value, field=field), expr)
Copy link

Copilot AI Jul 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accessing expr.args[0].value assumes the first argument is always a literal config name; this is brittle. Consider adding a dedicated config_name attribute or accessor on your Function subclasses to make this extraction safer.

Copilot uses AI. Check for mistakes.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quizá tendría sentido validarlo antes de intentar desempaquetarlo

quizá también tendría sentido mejorar la readability manteniendo el orden original y la opcionalidad de la config

@fullonic fullonic marked this pull request as ready for review July 2, 2025 09:08
Copy link

@XaviTorello XaviTorello left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Si lo acabamos de fortificar seguramente será fácilmente promocionable al repo original

Tiene sentido añadir algún test mínimo para blindarlo?

Versionamos de alguna manera? Agrupamos features?

super().__init__(Comp.search, ToTsVector(field), _expr)
if not isinstance(expr, Function):
expr = ToTsQuery(expr)
super().__init__(Comp.search, ToTsVector(config_name=expr.args[0].value, field=field), expr)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quizá tendría sentido validarlo antes de intentar desempaquetarlo

quizá también tendría sentido mejorar la readability manteniendo el orden original y la opcionalidad de la config

@fullonic fullonic force-pushed the feature/allow-pass-configuration-for-ToTsQuery branch from 76cbfe8 to 02a7f93 Compare December 29, 2025 08:24
@fullonic fullonic force-pushed the feature/allow-pass-configuration-for-ToTsQuery branch from b2e03a1 to 52d6aaa Compare December 29, 2025 08:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants