Asyncpg.Exceptions.AmbigousParameterError: не удалось определить тип данных параметра

Создаю конечную точку для поиска в FastAPI, но столкнулся с этой ошибкой:

asyncpg.exceptions.AmbiguousParameterError: could not determine data type of parameter $2

Я определил свой SQL-запрос в query.py:

GET_LOG_QUERY = """
SELECT *
FROM activities
WHERE entity = :entity
AND types_id = :types_id
AND (
    :search IS NULL OR :search = '' 
    OR full_name ILIKE :search
    OR email ILIKE :search
)

"""

и вот репозиторий:

class LogActivitiesRepository(BaseRepository):
    def __init__(self, db):
        super().__init__(db=db)

    async def get_activities(self, types_id: str, entity: str, search: Optional[str] = None) -> List[LogActivityModel]:
        search_pattern = f"%{search}%" if search else "%"
        records = await self.db.fetch_all(
            query=GET_LOG_QUERY,
            values = {
                "entity": entity_name,
                "types_id": types_id,
                "search": search_pattern
            }
        )
        if not records:
            return []
        return [LogActivityModel(**record._mapping) for record in records]

Если я не рассматриваю поле поиска, оно очень хорошо работает в наборе запросов, как в наборе запросов ниже:

GET_LOG_QUERY = """ ВЫБИРАТЬ * ИЗ активности_пользователя ГДЕ имя_объекта = :имя_объекта И tenant_id = :tenant_id; """

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
73
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

PostgreSQL не знает тип значения :search, поскольку он не определен ни в одной из таблиц запроса:

test# select $1 is null \bind 'x' \g
ERROR:  could not determine data type of parameter $1

Возможно, вам удастся обойтись без приведения :search там, где оно используется в правой части сравнения:

GET_LOG_QUERY = """
SELECT *
FROM activities
WHERE entity = :entity
AND types_id = :types_id
AND (
    :search::varchar IS NULL OR :search::varchar = '' 
    OR full_name ILIKE :search
    OR email ILIKE :search
)
"""

Однако, вероятно, лучше вычислить логическое выражение на уровне Python и заменить :search IS NULL OR :search = '' результатом.

GET_LOG_QUERY = """
SELECT *
FROM activities
WHERE entity = :entity
AND types_id = :types_id
AND (
    :no_pattern 
    OR full_name ILIKE :search
    OR email ILIKE :search
)
"""

...

        no_pattern = not bool(search_pattern)
        records = await self.db.fetch_all(
            query=GET_LOG_QUERY,
            values = {
                "entity": entity_name,
                "types_id": types_id,
                "search": search_pattern,
                "no_pattern": no_pattern,
            }
        )

Другие вопросы по теме