diff --git a/c2corg_api/models/association_views.py b/c2corg_api/models/association_views.py index d2fea4ec9..d5f2fe034 100644 --- a/c2corg_api/models/association_views.py +++ b/c2corg_api/models/association_views.py @@ -96,7 +96,7 @@ def _get_select_waypoints_for_routes_aggregated(): type_=postgresql.ARRAY(Integer)).label('waypoint_ids') ]). \ select_from(all_waypoints). \ - group_by(all_waypoints.c.route_id) + group_by(all_waypoints.c.route_id).subquery() class WaypointsForRoutesView(Base): @@ -157,7 +157,7 @@ def _get_select_waypoints_for_outings_aggregated(): type_=postgresql.ARRAY(Integer)).label('waypoint_ids') ]). \ select_from(waypoints_for_outings). \ - group_by(waypoints_for_outings.c.outing_id) + group_by(waypoints_for_outings.c.outing_id).subquery() class WaypointsForOutingsView(Base): @@ -200,7 +200,7 @@ def _get_select_users_for_outings_aggregated(): Association.parent_document_type == user_type, Association.child_document_type == outing_type )). \ - group_by(Association.child_document_id) + group_by(Association.child_document_id).subquery() class UsersForOutingsView(Base): @@ -243,7 +243,7 @@ def _get_select_routes_for_outings_aggregated(): Association.parent_document_type == route_type, Association.child_document_type == outing_type )). \ - group_by(Association.child_document_id) + group_by(Association.child_document_id).subquery() class RoutesForOutingsView(Base): @@ -280,7 +280,7 @@ def _get_select_users_for_routes_aggregated(): type_=postgresql.ARRAY(Integer)).label('user_ids') ]). \ select_from(DocumentTag). \ - group_by(DocumentTag.document_id) + group_by(DocumentTag.document_id).subquery() class UsersForRoutesView(Base): diff --git a/c2corg_api/models/feed.py b/c2corg_api/models/feed.py index 941d4b50e..61246e298 100644 --- a/c2corg_api/models/feed.py +++ b/c2corg_api/models/feed.py @@ -58,7 +58,8 @@ class FilterArea(Base): User.has_area_filter = column_property( select([func.count(FilterArea.area_id) > 0]). where(FilterArea.user_id == User.id). - correlate_except(FilterArea), + correlate_except(FilterArea). + scalar_subquery(), deferred=True ) User.feed_filter_areas = relationship('Area', secondary=FilterArea.__table__) @@ -98,7 +99,8 @@ class FollowedUser(Base): User.is_following_users = column_property( select([func.count(FollowedUser.followed_user_id) > 0]). where(FollowedUser.follower_user_id == User.id). - correlate_except(FollowedUser), + correlate_except(FollowedUser). + scalar_subquery(), deferred=True ) @@ -474,7 +476,7 @@ def update_langs_of_changes(document_id): DBSession.execute( DocumentChange.__table__.update(). where(DocumentChange.document_id == document_id). - values(langs=langs.select())) + values(langs=langs.select().scalar_subquery())) def get_linked_document(images_in): diff --git a/c2corg_api/security/roles.py b/c2corg_api/security/roles.py index 0db6153f3..fcb23db44 100644 --- a/c2corg_api/security/roles.py +++ b/c2corg_api/security/roles.py @@ -50,7 +50,7 @@ def is_valid_token(token): def add_or_retrieve_token(value, expire, userid): token = DBSession.query(Token). \ - filter(Token.value == value, User.id == userid).first() + filter(Token.value == value, Token.userid == userid).first() if not token: token = Token(value=value, expire=expire, userid=userid) DBSession.add(token) diff --git a/c2corg_api/views/document_delete.py b/c2corg_api/views/document_delete.py index d061fdb88..a5e4a75dc 100644 --- a/c2corg_api/views/document_delete.py +++ b/c2corg_api/views/document_delete.py @@ -256,8 +256,8 @@ def _delete_document(self, document_id, document_type, redirecting=False): def _remove_merged_documents(self, document_id, document_type): merged_document_ids = DBSession.query(ArchiveDocument.document_id). \ filter(ArchiveDocument.redirects_to == document_id).all() - for merged_document_id in merged_document_ids: - self._delete_document(merged_document_id, document_type, True) + for row in merged_document_ids: + self._delete_document(row.document_id, document_type, True) @resource(path='/documents/delete/{id}', cors_policy=cors_policy) @@ -365,10 +365,11 @@ def remove_from_cache(document_id): def _remove_versions(document_id): - history_metadata_ids = DBSession. \ - query(DocumentVersion.history_metadata_id). \ - filter(DocumentVersion.document_id == document_id). \ - all() + history_metadata_ids = [ + row.history_metadata_id for row in + DBSession.query(DocumentVersion.history_metadata_id)\ + .filter(DocumentVersion.document_id == document_id).all() + ] DBSession.query(DocumentVersion). \ filter(DocumentVersion.document_id == document_id). \ delete() @@ -391,8 +392,11 @@ def _remove_locale_versions(document_id, lang): subquery('t') # Gets the list of history_metadata_id associated only # to the current locale: - history_metadata_ids = DBSession.query(t.c.history_metadata_id). \ - filter(t.c.lang == lang).filter(t.c.cnt == 1).all() + history_metadata_ids = [ + row.history_metadata_id + for row in DBSession.query(t.c.history_metadata_id)\ + .filter(t.c.lang == lang).filter(t.c.cnt == 1).all() + ] DBSession.query(DocumentVersion). \ filter(DocumentVersion.document_id == document_id). \ @@ -413,7 +417,7 @@ def _remove_archive_locale(archive_clazz_locale, document_id, lang=None): archive_document_locale_ids = query.subquery() DBSession.execute(archive_clazz_locale.__table__.delete().where( getattr(archive_clazz_locale, 'id').in_( - archive_document_locale_ids) + archive_document_locale_ids.select()) )) query = DBSession.query(ArchiveDocumentLocale). \ @@ -431,12 +435,12 @@ def _remove_locale(clazz_locale, document_id, lang=None): document_locale_ids = query.subquery() # Remove links to comments (comments themselves are not removed) DBSession.execute(DocumentTopic.__table__.delete().where( - DocumentTopic.document_locale_id.in_(document_locale_ids) + DocumentTopic.document_locale_id.in_(document_locale_ids.select()) )) if clazz_locale: DBSession.execute(clazz_locale.__table__.delete().where( - getattr(clazz_locale, 'id').in_(document_locale_ids) + getattr(clazz_locale, 'id').in_(document_locale_ids.select()) )) query = DBSession.query(DocumentLocale). \ @@ -463,7 +467,7 @@ def _remove_archive(archive_clazz, document_id): filter(ArchiveDocument.document_id == document_id). \ subquery() DBSession.execute(archive_clazz.__table__.delete().where( - getattr(archive_clazz, 'id').in_(archive_document_ids) + getattr(archive_clazz, 'id').in_(archive_document_ids.select()) )) DBSession.query(ArchiveDocument). \ diff --git a/c2corg_api/views/document_info.py b/c2corg_api/views/document_info.py index 7e5509950..c8d629dfd 100644 --- a/c2corg_api/views/document_info.py +++ b/c2corg_api/views/document_info.py @@ -89,12 +89,20 @@ def _load_document_info(self, document_id, lang, clazz): filter(getattr(clazz, 'document_id') == document_id). \ options(joinedload(locales_type_eager). load_only(*locales_load_only)) + document_query = add_load_for_profiles(document_query, clazz) document = document_query.first() if not document: raise HTTPNotFound('document not found') + if document.document_id: + # TODO: find a better way than this workaround which calls + # `document_id` before `set_best_locale` expunge the object + # leading in: sqlalchemy.orm.exc.DetachedInstanceError: + # Parent instance
is not bound to a Session; + # deferred load operation of attribute 'document_id' cannot proceed + pass set_best_locale([document], lang) if document.redirects_to: diff --git a/pytest.ini b/pytest.ini index b0e5a945f..3ee4349c7 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,3 +1,7 @@ [pytest] filterwarnings = - ignore::DeprecationWarning \ No newline at end of file + ignore::DeprecationWarning:cornice + ignore::DeprecationWarning:pyramid + ignore::DeprecationWarning:elasticsearch + ignore::DeprecationWarning:pkg_resources + ignore::DeprecationWarning:jwt \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 87886b16a..84fe5b3cd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -27,7 +27,7 @@ redis==5.2.1 requests==2.32.3 setuptools==77.0.3 Shapely==2.0.7 -SQLAlchemy==1.3.24 +SQLAlchemy==1.4.7 transaction==5.0 waitress==3.0.2 zope.sqlalchemy==3.1