с SQLAlchemy.экскавация.ProgrammingError: (psycopg2.ProgrammingError) не может адаптировать тип "свойство"
Я пытаюсь запросить Version
, где я хочу получить объекты обратно, где их атрибут max_version_number
равен version_number
:
latest_versions =
dbSession.query(Version).filter(Version.max_version_number == Version.number_version)
Это приводит к ошибке:
Traceback (most recent call last):
...
...
filter(Version.max_version_number == Version.version_number).
File "c:python27libsite-packagessqlalchemyormquery.py", line 2588, in all
return list(self)
File "c:python27libsite-packagessqlalchemyormquery.py", line 2736, in __iter__
return self._execute_and_instances(context)
File "c:python27libsite-packagessqlalchemyormquery.py", line 2751, in _execute_and_instances
result = conn.execute(querycontext.statement, self._params)
File "c:python27libsite-packagessqlalchemyenginebase.py", line 914, in execute
return meth(self, multiparams, params)
File "c:python27libsite-packagessqlalchemysqlelements.py", line 323, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "c:python27libsite-packagessqlalchemyenginebase.py", line 1010, in _execute_clauseelement
compiled_sql, distilled_params
File "c:python27libsite-packagessqlalchemyenginebase.py", line 1146, in _execute_context
context)
File "c:python27libsite-packagessqlalchemyenginebase.py", line 1341, in _handle_dbapi_exception
exc_info
File "c:python27libsite-packagessqlalchemyutilcompat.py", line 200, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "c:python27libsite-packagessqlalchemyenginebase.py", line 1139, in _execute_context
context)
File "c:python27libsite-packagessqlalchemyenginedefault.py", line 450, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) can't adapt type 'property' [SQL: 'SELECT "Versions".id AS "Versions_id", "Links".id AS "Links_id", "Entities".id AS "Entities_id", "SimpleEntities".stalker_version AS "SimpleEntities_stalker_version", "SimpleEntities".id AS "SimpleEntities_id", "SimpleEntities".entity_type AS "SimpleEntities_entity_type", "SimpleEntities".name AS "SimpleEntities_name", "SimpleEntities".description AS "SimpleEntities_description", "SimpleEntities".created_by_id AS "SimpleEntities_created_by_id", "SimpleEntities".updated_by_id AS "SimpleEntities_updated_by_id", "SimpleEntities".date_created AS "SimpleEntities_date_created", "SimpleEntities".date_updated AS "SimpleEntities_date_updated", "SimpleEntities".type_id AS "SimpleEntities_type_id", "SimpleEntities".generic_text AS "SimpleEntities_generic_text", "SimpleEntities".thumbnail_id AS "SimpleEntities_thumbnail_id", "SimpleEntities".html_style AS "SimpleEntities_html_style", "SimpleEntities".html_class AS "SimpleEntities_html_class", "Links".original_filename AS "Links_original_filename", "Links".full_path AS "Links_full_path", "Versions".task_id AS "Versions_task_id", "Versions".take_name AS "Versions_take_name", "Versions".version_number AS "Versions_version_number", "Versions".is_published AS "Versions_is_published", "Versions".created_with AS "Versions_created_with", "Versions".parent_id AS "Versions_parent_id" nFROM "SimpleEntities" JOIN "Entities" ON "SimpleEntities".id = "Entities".id JOIN "Links" ON "Entities".id = "Links".id JOIN "Versions" ON "Links".id = "Versions".id nWHERE "Versions".version_number = %(version_number_1)s'] [parameters: {'version_number_1': <property object at 0x00000000060EF6D8>}]
Что я делаю не так?
Вот Модель Version
.
Это мой фактический запрос, который работает без проблем:
proj_id = 5
versions = Version.query.join(Task).filter(Task.project_id == proj_id).all()
...тем не менее, это возвращает все версии, и я хочу получить только те из них с наибольшим номером версии, возвращенным из запроса, поэтому я пытаюсь отфильтруйте и это.
1 ответ:
Проблема в том, что вы передаете объект дескриптора
property
(Version.max_version_number
) Для сравнения, который psycopg2 не имеет представления о том, как его адаптировать. Вместо этого вы должны использовать выражение SQL так или иначе.Чтобы получить строки с максимальными версиями, сгруппированными по задачам в project
project_id
, Вы, по-видимому, можете использовать DISTINCT ON в сочетании с ORDER BY в Postgresql:versions = Version.query\ .join(Task)\ .distinct(Version.task_id)\ .filter(Task.project_id == proj_id)\ .order_by(Version.task_id, Version.version_number.desc())\ .all()
Это вернет только 1
Version
наTask
, хотя, даже если несколько экземпляровVersion
совместно используют один и тот жеVersion.version_number
, который с другой стороны, это может показаться странным.Другой вариант-использовать подзапрос как своего рода поиск и присоединиться к нему:
from sqlalchemy import tuple_ max_per_task = dbSession.query(Version.task_id, func.max(Version.version_number).label('max'))\ .join(Task)\ .filter(Task.project_id == proj_id)\ .group_by(Version.task_id)\ .subquery() versions = Version.query\ .join(max_per_task, tuple_(max_per_task.c.task_id, max_per_task.c.max) == tuple_(Version.task_id, Version.version_number))\ .all()