Skip to content

Bump sqlalchemy from 2.0.51 to 2.0.52 - #21

Open
dependabot[bot] wants to merge 33 commits into
mainfrom
dependabot/pip/sqlalchemy-2.0.52
Open

Bump sqlalchemy from 2.0.51 to 2.0.52#21
dependabot[bot] wants to merge 33 commits into
mainfrom
dependabot/pip/sqlalchemy-2.0.52

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Aug 16, 2026

Copy link
Copy Markdown

Bumps sqlalchemy from 2.0.51 to 2.0.52.

Release notes

Sourced from sqlalchemy's releases.

2.0.52

Released: August 11, 2026

platform

  • [platform] [bug] Python 3.15 support has been added and tested, including minimal changes for full compatibility.

    References: #13477

orm

  • [orm] [bug] Fixed a result-column misalignment bug in ORM-enabled UPDATE statements where synchronize_session="fetch" is in use, either explicitly or because the statement uses constructs such as CTEs that implicitly select for it. Columns in rows returned by .returning() could be returned under incorrect keys (e.g. row[SomeClass.a] returning the value of a different column), a problem most likely to manifest under concurrent workloads. ORM DELETE statements were not affected.

    References: #13439

  • [orm] [bug] Fixed bug where a failed _orm.Session.bulk_insert_mappings(), _orm.Session.bulk_update_mappings() or _orm.Session.bulk_save_objects() call could leave the _orm.Session permanently in a "flushing" state, such as when the transaction could not be begun because a previous flush had left it needing a rollback. Unlike _orm.Session.flush(), the bulk methods set the internal flushing flag and began the transaction outside of the try/finally block that resets it, so that neither _orm.Session.rollback() nor _orm.Session.close() would clear it, and every subsequent flush would raise InvalidRequestError: Session is already flushing. Pull request courtesy Hamody We.

    References: #13485

  • [orm] [bug] Fixed issue where unpickling an ORM object that were loaded using loader options making use of wildcard tokens, such as _orm.load_only() or _orm.raiseload() with "*", would fail with KeyError or IndexError if the process doing the unpickling had not yet constructed a loader path making use of that same token. This would typically be observed when the object were unpickled in a separate process, such as with the spawn or forkserver multiprocessing start methods, the latter of which became the default on POSIX platforms as of Python 3.14. The internal collection of these tokens is now established up front, so that it is identical in every process.

... (truncated)

Commits

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Mark Vermeer added 30 commits August 7, 2026 13:33
Adds an explicit statement that Row Tracker is fully self-hosted with no
backend of ours in the loop, and calls out the AI coaching feature as the
one exception (opt-in, uses the user's own Anthropic key, sends only
minimal workout context). Also removes the Support/sponsorship section
for now.
Establishes 0.x.y SemVer going forward (major-zero: breaking changes
still possible in minor bumps). The version lives in a single VERSION
file, read once at app startup and exposed as an app_version Jinja
global — shown in a new site-wide footer and on the FAQ page subtitle,
replacing the hardcoded "June 2026" date that was already stale.

CHANGELOG.md backfills 0.1.0 through 0.9.0 from commit history, grouped
by what actually shipped in each burst of work, since nothing was
tagged contemporaneously.
… cache

Moved the version display from a centered footer line to a small,
low-opacity vX.Y.Z badge fixed to the bottom-right corner on every page.

While verifying it live, found that the service worker's static-asset
cache name was a hardcoded constant that never changed across deploys —
cache-first meant any CSS/JS update was invisible to a browser that had
already loaded the app once. sw.js is now rendered from a Jinja template
with CACHE_NAME tied to app_version, so every version bump invalidates
the old cache automatically instead of silently serving stale assets.
Fixes a real issue found while auditing the repo for public release: no
.dockerignore existed, so the real .env (with live credentials) and the
full .git history were being baked directly into every built Docker
image. The app never reads that in-image copy — all config comes from
os.environ via docker-compose's env_file — so excluding it is a pure
fix with no behavior change. Also fixes the README's placeholder clone
URL, a copyright-name casing mismatch between LICENSE.md and the README,
removes the unused python-dotenv dependency, and a couple of small
doc-sync items.

Does not cover the remaining open items from the same audit pass (a
leaked credential still present in git history, and a couple of
untracked-file cleanup questions) — those need a decision first.
Both were flagged in the public-readiness audit: designidea.webp is an
unreferenced design-reference image, and the two docs/superpowers/ files
are AI-agent implementation plans/specs, not user-facing documentation.
Untracked (git rm --cached) rather than deleted, and added to .gitignore
alongside the existing row-tracker-spec.md / docs/redesign-spec.md
convention — local copies are kept, just not part of the public repo.
The README said AI coaching was "the only feature that talks to a third
party," which stopped being true the moment the feedback form existed —
it emails the developer directly (hardcoded recipient, not configurable
via .env), using whatever Gmail credentials the deployer configured.
Added a dedicated Feedback section spelling out exactly what it does and
doesn't send, and cross-referenced it from the top privacy blurb.
…s audit

Removes _persist_refresh_token() from c2_api.py — unreachable (Concept2
issues a non-expiring bearer token, so nothing ever rotates it), and
wouldn't have worked reliably even if called (writes to .env inside the
container, which isn't a mounted file and no longer exists there at all
post the .dockerignore fix). Also fixes the module docstring, which
still described an OAuth token-exchange flow the code never implements.

This closes out the two-pass pre-public-release audit: git history is
clean (leaked credential scrubbed + revoked), the Docker image no longer
bakes in secrets, docs are accurate and cross-linked, stray files are
untracked, CONTRIBUTING.md and GitHub topics are in place, and the full
test suite (187 tests) passes against the final state.
Clicking Sync on a dashboard left open >1h returned 400 'request failed'
with a 'CSRF token has expired' log line. The token stays session-bound
regardless, so the 1-hour expiry was UX friction with no security benefit
for a single-user self-hosted app.
… AI coach's read

A new nav section that reads the full workout history and surfaces patterns in
plain language (best day, rest-day effect, pace/volume trends, fastest steady
stroke rate, session-length clusters, consistency, PB clustering). Each insight
clears a minimum-sample and significance check before it appears and is tagged
Strong pattern or Early signal; the strongest carry a recommendation.

Built as a rule-based engine (insights_engine.py) with facts separated from
phrasing, so an optional AI 'coach's read' (insights_ai.py, USE_AI_INSIGHTS,
off by default) can rephrase the computed facts without ever inventing a number.

Includes tests (11), README/FAQ/QUICKSTART + in-app twins, and .env.example.
…-proof

Tuned insight surfacing against real data. Day-of-week, rest-gap, and seasonal
pace effects were left gated — the signal is genuinely flat at the median, so
loosening would manufacture noise — while adding rules the data actually supports:

- Milestones section (years rowing, biggest day, hours on the erg, longest streak),
  rendered as a big-number 'stat' card with no confidence tag since they're facts.
- Year-over-year volume: meters Jan 1 -> today vs the same span last year.
- Pace-trend now measures steady pieces (20 min+) only, so a shift in workout mix
  can't masquerade as a pace change.

Adds 7 tests (18 total in the module); README/FAQ + in-app twins updated.
The rower emblem replaces the placeholder emoji in the desktop and mobile nav,
and the full ROW TRACKER lockup anchors the top of the Dashboard, switching
between the dark- and light-mode artwork with the theme. Source logos were
processed to transparent backgrounds (stray export badge and edge line removed)
and normalised to a shared frame so theme changes cause no size shift.
…ry instances

Default true (prod unchanged). Set RUN_SCHEDULER=false so a dev instance doesn't
run the nightly C2 sync/PB recalc/badge eval/backup and fire duplicate
notification emails alongside the instance that owns the live data.
Year-over-year and weekly-volume cards showed distances as '1,996k m' /
'56.0k m/week', an ambiguous kilo-metres hybrid that read like a typo. Now
rendered as consistent kilometres in detail text, pills, and sparkline labels.
… read

Covers the availability gate, the happy path (right model, briefing grounded in
the engine's real facts, system prompt forbids inventing numbers), and every
failure mode falling back to None. Runs with no API key — no real calls made.
All prior screenshots predated the logo (Aug 7, logo shipped Aug 10) and
still showed the old placeholder emoji nav. Retaken against the live app:
new branded nav + dashboard hero visible throughout, plus a new Insights
screenshot for the page that didn't exist when the originals were taken.
Swapped # 🚣 Row Tracker for a theme-switched logo banner using the same
<picture>/prefers-color-scheme trick GitHub renders correctly in READMEs —
dark artwork on a dark-mode viewer, light artwork on a light-mode one.
Image vulnerability scan (Docker Scout) found known CVEs in the base image's
bundled pip/setuptools/wheel/jaraco-context — never upgraded past whatever
shipped with python:3.11-slim. Now upgraded explicitly before installing app
dependencies, plus apt-get upgrade for OS packages so future rebuilds pick up
Debian security patches automatically. Verified on disk post-rebuild: real
fixes (setuptools 79.0.1->84.0.0, pip 24.0->26.2.1, etc.), no regressions —
two apparent new findings from the scanner (a stale setuptools version, a
pip-internal vendored msgpack copy) were confirmed to be scanner artifacts,
not real state of the image, by direct filesystem inspection.
Closes the last blind spot from the security review — the vendored copy had
no version pinned anywhere and nothing would catch it going stale. Pinned to
Chart.js 4.4.1 via jsDelivr with a sha384 integrity hash verified against the
actual served bytes, so a tampered/compromised CDN response fails to execute
rather than running silently.

Falls back to the local file (now byte-identical to the CDN version, not a
different unverified build) if the CDN is unreachable, keeping 'no external
dependencies required' true for offline/air-gapped use — the service worker
already pre-caches that file for offline PWA support regardless.

All 5 templates now share one partial (_chart_cdn.html) instead of duplicating
the script tag, with the version-bump recipe documented inline.

Verified in-browser: CDN loads (200), SRI passes with zero console errors,
Chart.version reports 4.4.1, fallback correctly stays dormant, charts render
on both Dashboard and the Charts pages.
…ocal time

Container had no TZ set, so the '3:00 AM' cron jobs (sync, PB recalc, badge
eval, backup) actually ran at 3:00 AM UTC — hours off from the FAQ/Quick
Start's documented 'Toronto time'. Added TZ to .env.example, defaulting to
America/Toronto to match the docs.
…g + last-synced indicator

- scheduler.py: CronTrigger doesn't inherit BackgroundScheduler's timezone
  kwarg unless given its own — every job's trigger now gets it explicitly
  (sourced from TZ, defaulting to America/Toronto). v0.9.12's TZ env var
  only worked by coincidence; this is the actual fix.
- c2_api.py: a bad/expired token (401) or network failure was
  indistinguishable from 'nothing new to sync' — now surfaced as a real
  error via C2ApiClient.last_error instead of silently swallowed.
- New SyncStatus model + sync_status.py: tracks last attempt/success/error,
  shared by the nightly scheduler and the manual /sync route.
- Dashboard: 'last synced' indicator next to the Sync button.
- notify.py: notify_job_failure() emails NOTIFY_EMAIL when the nightly
  sync, PB recalc, badge eval, or backup job fails — previously log-only.
- Manual sync button's frontend now treats the /sync route's 'partial'
  status as a failure (it was falling through to the success branch).
- 227 tests passing, 12 new.
Added to the desktop nav when Insights shipped in 0.9.5, never added to
the mobile hamburger drawer, so it's been invisible on phones/tablets
since then. Added the link, plus a regression test that diffs desktop
vs. mobile nav hrefs so a future nav addition can't repeat this.
The 228-test pytest suite has existed for a while but nothing ran it
automatically. Adds .github/workflows/tests.yml: Python 3.11 (matching
the Docker base image), pip caching, runs on every push to main and
every PR. Status badge + license badge added to README; CONTRIBUTING.md
updated to mention the automated check.
Mark Vermeer and others added 3 commits August 16, 2026 07:56
actions/checkout@v4 and actions/setup-python@v5 were both being forced
onto a deprecated Node target on the first CI run. Bumped to @v7/@v7.
Weekly automated PRs across all three ecosystems this repo actually
uses. Every Dependabot PR gets checked by the CI workflow added in
0.10.2, so a breaking bump fails the check instead of merging silently.
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.51 to 2.0.52.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

---
updated-dependencies:
- dependency-name: sqlalchemy
  dependency-version: 2.0.52
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot @github

dependabot Bot commented on behalf of github Aug 16, 2026

Copy link
Copy Markdown
Author

Labels

The following labels could not be found: dependencies. Please create it before Dependabot can add it to a pull request.

Please fix the above issues or remove invalid values from dependabot.yml.

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.

0 participants