wrolpi/modules/videos/test
lrnselfreliance cfbed9e4d7
db: serializers read only loaded data (#777)
* db: serializers read only loaded data

Serializing a model must not query.  A lazy load there is a hidden query per row (search serialized 24 rows
with 55 statements), and would be a `MissingGreenlet` error under an async Session.

- `wrolpi.db.no_db_access(reason)` and `@serializer` (on every model `__json__`, and around `json_response`):
  an engine `before_cursor_execute` listener raises `UnexpectedQuery` during tests, and in production logs once
  per serializer and lets the query run.  Tests record each trip as well, and the autouse
  `no_unexpected_queries` fixture fails a test even when the code caught the error (Video's serializer was
  swallowing its per-row loads of the deferred `ffprobe_json`).
- Relationships serializers read load with their parent: `selectin` for FileGroup.tag_files and
  Collection.downloads; `joined` for TagFile.tag, Collection.tag, Channel.collection, Video.channel,
  Archive.collection, ZimSubscription.download, CollectionItem.zim, and the file_group of Video, Archive, Doc,
  Zim and CollectionItem.
- Search and the Video lookups the video page uses load the deferred `ffprobe_json` (`undefer`).
- `wrolpi/test/test_serializers.py`: every serialized model, freshly loaded, serializes without SQL.

Search: 55 -> 5 statements for 24 videos (31 -> 5 for archives), and a few ms faster locally.

Not in this change: guarding the `dict()` serializers and `expire_on_commit=False`, which go together (about 50
serialize-after-commit sites, and 40 tests that read values changed elsewhere after a commit).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* db: serializer loads per query; the guard ignores transaction control

The query guard reported the engine's own BEGIN (emitted through the same event as the first statement on a
Session with no open transaction) instead of the lazy load after it, and in production that BEGIN used up the
one warning per serializer.  Transaction-control statements are now ignored.

Mapper-level eager loads reached background code: every Video/Archive load in the modelers (one per file,
inside the write transaction) joined file_group/channel/collection/tag and selectin-loaded the Collection's
Download rows with their yt-dlp info_json.  A second refresh of 100 videos took 0.40 s instead of 0.16 s.

Serializer needs are now declared per model (`json_options()`) and added only by the queries whose results
are serialized; Download.info_json is deferred there (no serializer reads it).  Mapper defaults keep only
narrow joins nearly every use needs: TagFile.tag, Collection.tag and Channel.collection.  A second refresh is
back to master's statement count and time; search still drops from 55 to 3 statements.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 18:28:08 -06:00
..
__init__.py A new start 2021-11-01 16:43:09 -06:00
test_api.py db: request-path library functions use the request's connection (#774) 2026-10-04 11:05:20 -06:00
test_audio_modeling.py files: shared modeler batch loop for video, doc, zim, archive (#722) 2026-09-24 16:47:46 -06:00
test_channel_directory_scenarios.py db: write intent is the opt-in, not a second session helper 2026-08-07 20:15:50 -06:00
test_channel_refresh_events.py videos: silence the automatic channel refresh before downloads (#671) 2026-08-20 15:15:18 -06:00
test_channel_refresh_external_files.py Displaying download progress (speed, eta) for file and video downloads. 2026-03-12 19:31:35 -06:00
test_channels_config.py FileGroups in Collections can be reorganized in the Collection's directory. 2026-01-31 18:08:41 -07:00
test_common.py Jobs queue, video Edit dropdown: transcode/remux, edit title & description (#711) 2026-09-16 19:25:23 -06:00
test_cookies.py Using shared context to sync cookies between processes. 2026-02-22 14:32:27 -07:00
test_downloader.py Jobs queue, video Edit dropdown: transcode/remux, edit title & description (#711) 2026-09-16 19:25:23 -06:00
test_lib.py db: request-path library functions use the request's connection (#774) 2026-10-04 11:05:20 -06:00
test_models.py Handling when skip_urls is a None. Logging a warning (and ignoring) when duplicate json files are in a Video FileGroup. 2026-03-13 15:27:43 -06:00
test_transcode.py Jobs queue, video Edit dropdown: transcode/remux, edit title & description (#711) 2026-09-16 19:25:23 -06:00
test_transcode_audio.py videos: transcode can remove the audio stream (silent video) (#737) 2026-09-26 17:49:14 -06:00
test_transcode_job.py videos: hide the transcoder's temporary output from the file refresh (#731) 2026-09-26 14:59:51 -06:00
test_video.py db: serializers read only loaded data (#777) 2026-10-04 18:28:08 -06:00
test_video_edit.py db: request-path library functions use the request's connection (#774) 2026-10-04 11:05:20 -06:00
test_video_modeler_loop.py Fixing bug where not all archives were modeled. 2025-12-18 17:19:57 -07:00
test_video_url_resolver.py Trying to get existing channel using more variations of Youtube URLs. 2026-03-20 17:26:51 -06:00