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

Fix type errors in SQL #903

Merged
merged 2 commits into from
Dec 20, 2024
Merged

Fix type errors in SQL #903

merged 2 commits into from
Dec 20, 2024

Conversation

uuiid
Copy link
Contributor

@uuiid uuiid commented Dec 20, 2024

Problem
Query parameter start_date in URL/data/tasks/open tasks, Due_date will generate SQL type errors

[2024-12-20 14:42:12 +0800] [23539] [ERROR] Error handling request //data/tasks/open-tasks?person_id=240e9b81-7156-46f8-83bd-77711515fd6c&page=1&start_date=2024-11-20%2000:00:00
Traceback (most recent call last):
  File "/opt/zou/env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1967, in _exec_single_context
    self.dialect.do_execute(
  File "/opt/zou/env/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 941, in do_execute
    cursor.execute(statement, parameters)
  File "/opt/zou/env/lib/python3.10/site-packages/psycopg/cursor.py", line 97, in execute
    raise ex.with_traceback(None)
psycopg.errors.UndefinedFunction: operator does not exist: timestamp without time zone >= character varying
LINE 5: ...on AND person.id = $3::UUID)) AND task.start_date >= $4::VAR...
                                                             ^
HINT:  No operator matches the given name and argument types. You might need to add explicit type casts.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/opt/zou/env/lib/python3.10/site-packages/gunicorn/workers/base_async.py", line 54, in handle
    self.handle_request(listener_name, req, client, addr)
  File "/opt/zou/env/lib/python3.10/site-packages/gunicorn/workers/ggevent.py", line 127, in handle_request
    super().handle_request(listener_name, req, sock, addr)
  File "/opt/zou/env/lib/python3.10/site-packages/gunicorn/workers/base_async.py", line 107, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
  File "/opt/zou/env/lib/python3.10/site-packages/flask/app.py", line 1536, in __call__
    return self.wsgi_app(environ, start_response)
  File "/opt/zou/env/lib/python3.10/site-packages/flask/app.py", line 1514, in wsgi_app
    response = self.handle_exception(e)
  File "/opt/zou/env/lib/python3.10/site-packages/flask_restful/__init__.py", line 298, in error_router
    return original_handler(e)
  File "/opt/zou/env/lib/python3.10/site-packages/flask_restful/__init__.py", line 298, in error_router
    return original_handler(e)
  File "/opt/zou/env/lib/python3.10/site-packages/flask_restful/__init__.py", line 298, in error_router
    return original_handler(e)
  [Previous line repeated 20 more times]
  File "/opt/zou/env/lib/python3.10/site-packages/flask/app.py", line 1511, in wsgi_app
    response = self.full_dispatch_request()
  File "/opt/zou/env/lib/python3.10/site-packages/flask/app.py", line 919, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/opt/zou/env/lib/python3.10/site-packages/flask_restful/__init__.py", line 298, in error_router
    return original_handler(e)
  File "/opt/zou/env/lib/python3.10/site-packages/flask_restful/__init__.py", line 298, in error_router
    return original_handler(e)
  File "/opt/zou/env/lib/python3.10/site-packages/flask_restful/__init__.py", line 298, in error_router
    return original_handler(e)
  [Previous line repeated 20 more times]
  File "/opt/zou/env/lib/python3.10/site-packages/flask/app.py", line 917, in full_dispatch_request
    rv = self.dispatch_request()
  File "/opt/zou/env/lib/python3.10/site-packages/flask/app.py", line 902, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
  File "/opt/zou/env/lib/python3.10/site-packages/flask_restful/__init__.py", line 489, in wrapper
    resp = resource(*args, **kwargs)
  File "/opt/zou/env/lib/python3.10/site-packages/flask/views.py", line 110, in view
    return current_app.ensure_sync(self.dispatch_request)(**kwargs)  # type: ignore[no-any-return]
  File "/opt/zou/env/lib/python3.10/site-packages/flask_restful/__init__.py", line 604, in dispatch_request
    resp = meth(*args, **kwargs)
  File "/opt/zou/env/lib/python3.10/site-packages/flask_jwt_extended/view_decorators.py", line 170, in decorator
    return current_app.ensure_sync(fn)(*args, **kwargs)
  File "/opt/zou/env/lib/python3.10/site-packages/zou/app/blueprints/tasks/resources.py", line 1758, in get
    return tasks_service.get_open_tasks(
  File "/opt/zou/env/lib/python3.10/site-packages/zou/app/services/tasks_service.py", line 2018, in get_open_tasks
    ) in query.limit(limit).all():
  File "/opt/zou/env/lib/python3.10/site-packages/sqlalchemy/orm/query.py", line 2673, in all
    return self._iter().all()  # type: ignore
  File "/opt/zou/env/lib/python3.10/site-packages/sqlalchemy/orm/query.py", line 2827, in _iter
    result: Union[ScalarResult[_T], Result[_T]] = self.session.execute(
  File "/opt/zou/env/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 2362, in execute
    return self._execute_internal(
  File "/opt/zou/env/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 2247, in _execute_internal
    result: Result[Any] = compile_state_cls.orm_execute_statement(
  File "/opt/zou/env/lib/python3.10/site-packages/sqlalchemy/orm/context.py", line 305, in orm_execute_statement
    result = conn.execute(
  File "/opt/zou/env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1418, in execute
    return meth(
  File "/opt/zou/env/lib/python3.10/site-packages/sqlalchemy/sql/elements.py", line 515, in _execute_on_connection
    return connection._execute_clauseelement(
  File "/opt/zou/env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1640, in _execute_clauseelement
    ret = self._execute_context(
  File "/opt/zou/env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1846, in _execute_context
    return self._exec_single_context(
  File "/opt/zou/env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1986, in _exec_single_context
    self._handle_dbapi_exception(
  File "/opt/zou/env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 2355, in _handle_dbapi_exception
    raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
  File "/opt/zou/env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1967, in _exec_single_context
    self.dialect.do_execute(
  File "/opt/zou/env/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 941, in do_execute
    cursor.execute(statement, parameters)
  File "/opt/zou/env/lib/python3.10/site-packages/psycopg/cursor.py", line 97, in execute
    raise ex.with_traceback(None)
sqlalchemy.exc.ProgrammingError: (psycopg.errors.UndefinedFunction) operator does not exist: timestamp without time zone >= character varying
LINE 5: ...on AND person.id = $3::UUID)) AND task.start_date >= $4::VAR...
                                                             ^
HINT:  No operator matches the given name and argument types. You might need to add explicit type casts.
[SQL: SELECT task.name AS task_name, task.description AS task_description, task.priority AS task_priority, task.difficulty AS task_difficulty, task.duration AS task_duration, task.estimation AS task_estimation, task.completion_rate AS task_completion_rate, task.retake_count AS task_retake_count, task.sort_order AS task_sort_order, task.start_date AS task_start_date, task.due_date AS task_due_date, task.real_start_date AS task_real_start_date, task.end_date AS task_end_date, task.done_date AS task_done_date, task.last_comment_date AS task_last_comment_date, task.nb_assets_ready AS task_nb_assets_ready, task.data AS task_data, task.shotgun_id AS task_shotgun_id, task.last_preview_file_id AS task_last_preview_file_id, task.project_id AS task_project_id, task.task_type_id AS task_task_type_id, task.task_status_id AS task_task_status_id, task.entity_id AS task_entity_id, task.assigner_id AS task_assigner_id, task.id AS task_id, task.created_at AS task_created_at, task.updated_at AS task_updated_at, project.name AS project_name, project.has_avatar AS project_has_avatar, entity.id AS entity_id, entity.name AS entity_name, entity.description AS entity_description, entity.data AS entity_data, entity.preview_file_id AS entity_preview_file_id, entity_type.name AS entity_type_name, entity.canceled AS entity_canceled, entity.parent_id AS entity_parent_id, entity.source_id AS entity_source_id, sequence.name AS sequence_name, episode.id AS episode_id, episode.name AS episode_name, task_type.name AS task_type_name, task_type.for_entity AS task_type_for_entity, task_status.name AS task_status_name, task_type.color AS task_type_color, task_status.color AS task_status_color, task_status.short_name AS task_status_short_name 
FROM task JOIN task_type ON task.task_type_id = task_type.id JOIN task_status ON task.task_status_id = task_status.id JOIN entity ON entity.id = task.entity_id JOIN entity_type ON entity_type.id = entity.entity_type_id JOIN project ON project.id = task.project_id JOIN project_status ON project_status.id = project.project_status_id LEFT OUTER JOIN entity AS sequence ON sequence.id = entity.parent_id LEFT OUTER JOIN entity AS episode ON episode.id = sequence.parent_id 
WHERE project_status.name = %(name_1)s::VARCHAR AND task_type.for_entity != %(for_entity_1)s::VARCHAR AND (EXISTS (SELECT 1 
FROM person, assignations 
WHERE task.id = assignations.task AND person.id = assignations.person AND person.id = %(id_1)s::UUID)) AND task.start_date >= %(start_date_1)s::VARCHAR ORDER BY project.name, episode.name, sequence.name, entity_type.name, entity.name, task_type.name 
 LIMIT %(param_1)s::INTEGER OFFSET %(param_2)s::INTEGER]
[parameters: {'name_1': 'Open', 'for_entity_1': 'Concept', 'id_1': '240e9b81-7156-46f8-83bd-77711515fd6c', 'start_date_1': '2024-11-20 00:00:00', 'param_1': 100, 'param_2': 0}]
(Background on this error at: https://sqlalche.me/e/20/f405)

Solution
Perform type conversion

@EvanBldy
Copy link
Member

EvanBldy commented Dec 20, 2024

Hi @uuiid,
Thanks for the suggestion, I made a little change using sqlalchemy.sql.func.cast to do the cast instead of datetime (it's almost the same in fine but if we change the type of the SQL columns it will automatically change the cast).

@EvanBldy EvanBldy merged commit 0b1b979 into cgwire:main Dec 20, 2024
2 checks passed
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