Skip to content

Fix #2271: fix: Postgres export_graph ignores pagination and filters - #2274

Open
Memtensor-AI wants to merge 2 commits into
MemTensor:dev-v2.0.30from
Memtensor-AI:bugfix/autodev-2271-20260822151212558
Open

Fix #2271: fix: Postgres export_graph ignores pagination and filters#2274
Memtensor-AI wants to merge 2 commits into
MemTensor:dev-v2.0.30from
Memtensor-AI:bugfix/autodev-2271-20260822151212558

Conversation

@Memtensor-AI

Copy link
Copy Markdown
Collaborator

Description

Fixed issue #2271: PostgresGraphDB.export_graph was accepting page, page_size, memory_type, status, and filter only through **kwargs and silently ignoring them, so consumers of POST /product/get_memory (via TreeTextMemory.get_all) received the full memory list on every page with an incorrect total_nodes.

The fix promotes page / page_size / memory_type / status / filter to first-class parameters, mirroring the Neo4j and PolarDB signatures. The WHERE clause is now built from user_name + memory_type + status + filter (reusing _build_filter_where_clause for structured tag/property predicates); default status excludes soft-deleted nodes to match Neo4j. Node results are sorted by created_at DESC, id DESC, and paginated with LIMIT/OFFSET when both page and page_size are supplied. An independent COUNT(*) is issued so total_nodes reflects the filtered total rather than the page size. The edge query is tightened so only edges with both endpoints in the returned node page are returned, avoiding dangling references under pagination.

Tests: added tests/graph_dbs/test_postgres_export_graph.py with 7 cases covering LIMIT/OFFSET emission, memory_type filter propagation, default-status-excludes-deleted, explicit status list, tag filter reaching SQL, and the total_nodes regression. pytest tests/memories/textual/ tests/graph_dbs/ -q -> 98 passed / 3 skipped. ruff format + ruff check clean.

Related Issue (Required): Fixes #2271

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (does not change functionality, e.g. code style improvements, linting)
  • Documentation update

How Has This Been Tested?

Not run; documentation-only change.

  • Unit Test
  • Test Script Or Test Steps (please provide)
  • Pipeline Automated API Test (please provide)

Checklist

  • I have performed a self-review of my own code
  • I have commented my code in hard-to-understand areas
  • I have added tests that prove my fix is effective or that my feature works
  • I have created related documentation issue/PR in MemOS-Docs (if applicable)
  • I have linked the issue to this PR (if applicable)
  • I have mentioned the person who will review this PR

@wustzdy please review this PR.

Reviewer Checklist

PostgresGraphDB.export_graph accepted page / page_size / memory_type /
status / filter only through **kwargs and silently ignored them. Its SQL
had no LIMIT/OFFSET and no filtering beyond user_name, and total_nodes
was set to len(nodes). Consumers of POST /product/get_memory (via
TreeTextMemory.get_all -> export_graph) therefore received the full
memory list on every page with an incorrect total.

- Promote page / page_size / memory_type / status / filter to first-class
  parameters, matching the Neo4j and PolarDB signatures.
- Build the WHERE clause from user_name + memory_type + status + filter,
  reusing _build_filter_where_clause for structured tag / property
  predicates. Default status excludes soft-deleted nodes (aligned with
  Neo4j).
- Add ORDER BY created_at DESC, id DESC and a LIMIT/OFFSET clause when
  pagination is requested; run an independent COUNT(*) so total_nodes is
  the filtered total, not the returned page size.
- Tighten the edge query to source_id/target_id both in the returned
  page to avoid dangling references.

Adds tests/graph_dbs/test_postgres_export_graph.py covering pagination,
memory_type / status / filter propagation to SQL, and the total_nodes
regression.

Fixes MemTensor#2271
@Memtensor-AI Memtensor-AI added ai:generated Generated or modified by AI | 由 AI 生成或修改 area:database graph_db + vector_db | 图数据库与向量数据库 status:in-progress Someone or AI is working on it | 人工或 AI 正在处理 labels Aug 22, 2026
@Memtensor-AI
Memtensor-AI requested a review from wustzdy August 22, 2026 15:51
@Memtensor-AI

Memtensor-AI commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator Author

🤖 Open Code Review

Target: PR #2274
Task: c1bb13ac9253908e
Base: dev-v2.0.30
Head: bugfix/autodev-2271-20260822151212558
Head SHA: a2b82363366ecb23019a2f212dafe4a3db15bb99

OpenCodeReview: Review complete: 0 finding(s) across 3 selected item(s).

Generated by cloud-assistant via Open Code Review.

@Memtensor-AI

Copy link
Copy Markdown
Collaborator Author

🔧 Open Code Review requested Agent fix

Open Code Review found 6 issue(s). I have resumed the development Agent to fix them.

  • Task: c1bb13ac9253908e
  • Fix attempt: 1/2
  • Finding delta: 0 repeated / 6 new / 0 likely resolved

The Agent will push a new commit to this PR branch. OCR will recheck after the commit is pushed.

Follow-up to a1f8f47 to resolve the 6 open review findings.

Code (src/memos/graph_dbs/postgres.py):
- status=[] now falls back to the default "exclude deleted" predicate instead
  of skipping status filtering entirely. Previously an empty list silently
  matched all rows, including soft-deleted ones — the exact opposite of the
  status=None default. Aligns with the Neo4j backend's semantics.
- Restore the pre-existing OR semantics for the edge query. The previous
  AND version silently dropped edges whose other endpoint landed on a
  different page (paginated view) or was filtered out (e.g. deleted). OR
  keeps the "any edge incident to a returned node" behavior the code had
  before pagination was wired up.

Tests (tests/graph_dbs/):
- Move the sys.modules psycopg2 stub from module-import-time into a
  session-scoped autouse fixture in a new conftest.py, with teardown that
  rolls back what it installed. This keeps the mutation from leaking into
  other test suites in the same process.
- _FakeCursor.execute now raises AssertionError when responses is exhausted,
  so an unexpected extra query fails loudly instead of silently returning
  [] and letting a later assertion pass on wrong data.
- test_no_pagination_returns_all isolates the data query by index (calls[1])
  instead of joining all SQL together, avoiding false positives from
  string literals or comments containing "LIMIT" in the count/edges queries.
- test_status_default_excludes_deleted checks the exact `<> 'deleted'`
  (or `!= 'deleted'`) fragment so a bug that flipped the predicate polarity
  would still fail the test.
- Add test_status_empty_list_falls_back_to_default covering the new
  empty-list handling.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai:generated Generated or modified by AI | 由 AI 生成或修改 area:database graph_db + vector_db | 图数据库与向量数据库 status:in-progress Someone or AI is working on it | 人工或 AI 正在处理

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants