Skip to content

UN-2808 [FIX] Added support for {column_name}_v2 columns in destination DB connectors#1538

Merged
kirtimanmishrazipstack merged 4 commits into
mainfrom
UN-2808-db-connector-column-v2-fix
Sep 16, 2025
Merged

UN-2808 [FIX] Added support for {column_name}_v2 columns in destination DB connectors#1538
kirtimanmishrazipstack merged 4 commits into
mainfrom
UN-2808-db-connector-column-v2-fix

Conversation

@kirtimanmishrazipstack

@kirtimanmishrazipstack kirtimanmishrazipstack commented Sep 16, 2025

Copy link
Copy Markdown
Contributor

What

  • {column_name}_v2 will be added to all destination connectors

Why

  • This column was added when we were migrating from earlier existent table from user

How

Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)

  • N/A

Database Migrations

  • N/A

Env Config

  • N/A

Relevant Docs

Related Issues or PRs

Dependencies Versions

Notes on Testing

  • Testing with running integration test locally

Screenshots

Checklist

I have read and understood the Contribution Guidelines.

@coderabbitai

coderabbitai Bot commented Sep 16, 2025

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features
    • Smarter handling when writing JSON to single-column destinations: automatically detects available companion columns and mirrors data when appropriate for better compatibility.
  • Bug Fixes
    • Reduced write errors by conditionally populating secondary columns based on table metadata.
    • Ensures consistent result formatting whether data is a string or structured JSON.
  • Style
    • Minor log message wording improvement for consistency.

Walkthrough

get_columns_and_values (WRITE_JSON_TO_A_SINGLE_COLUMN) now computes a has_v2_col flag from table_info (true when table_info is None, empty, or contains the _v2 column case-insensitively; false when table_info is provided, non-empty, and lacks the _v2 column) and populates the original single column always and the _v2 column only when has_v2_col is true. A log message in insert_into_db was renamed from "table info" to "table_info".

Changes

Cohort / File(s) Summary
DB column population logic
backend/workflow_manager/endpoint_v2/database_utils.py
For WRITE_JSON_TO_A_SINGLE_COLUMN, introduced v2_col_name and has_v2_col derived from table_info. Always set values[single_column_name]; set values[v2_col_name] only when has_v2_col is true. Handles both string (wrapped as {"result": data}) and non-string branches. Other logic unchanged.
Logging text tweak
backend/workflow_manager/endpoint_v2/destination.py
Changed debug/info text from "table info" to "table_info" in insert_into_db; no functional changes.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as Caller
    participant DBUtils as get_columns_and_values
    participant TableInfo as table_info source

    Caller->>DBUtils: request with column_mode=WRITE_JSON_TO_A_SINGLE_COLUMN, data, single_column_name
    DBUtils->>TableInfo: read table_info (may be None/empty or contain columns)
    alt table_info is None or empty or contains single_column_name_v2
        DBUtils-->>DBUtils: has_v2_col = true
        DBUtils-->>Caller: set values[single_column] = data (or {"result": data} if string)
        DBUtils-->>Caller: set values[single_column_v2] = same payload
    else table_info provided and lacks single_column_name_v2
        DBUtils-->>DBUtils: has_v2_col = false
        DBUtils-->>Caller: set values[single_column] = data (or {"result": data} if string)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The PR description provides brief What and Why sections but leaves the How section empty and marks several template fields as N/A or omits them entirely, including Database Migrations, Env Config, Related Issues/PRs, Dependencies, and detailed Notes on Testing. The repository template specifically requires the "Can this PR break any existing features" section to be filled with an explanation and the current "N/A" does not document risk, mitigation, or rationale. Because multiple required template fields are missing or incomplete, the description is insufficient for reviewers to assess scope and risk. Please complete the template by adding a concise "How" that summarizes the code changes and the conditions under which {column_name}_v2 is populated, explicitly state whether this can break existing features with mitigation steps or a rationale if not, and fill Database Migrations and Env Config sections as applicable. Include testing details (what integration tests were run, steps to reproduce, and expected outcomes), reference any related issues or PRs, and confirm the checklist items. Once these sections are populated reviewers will have the necessary context to approve merging.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly and accurately summarizes the primary change — adding support for {column_name}_v2 columns in destination DB connectors — and aligns with the PR objective and the code changes that conditionally populate _v2 columns. It is concise, specific, and free of noisy elements like file lists or emojis, making it easy for a reviewer scanning history to understand the main intent. The inclusion of the ticket prefix (UN-2808) is acceptable if it follows repository conventions.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch UN-2808-db-connector-column-v2-fix

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
backend/workflow_manager/endpoint_v2/destination.py (1)

374-375: Lower log level and avoid leaking engine/schema details.

Info-level logging of engine repr and full table_info can be noisy and may expose internals. Prefer debug and log minimal, non-sensitive bits.

-logger.info(
-    f"destination connector engine: {engine} with table_info: {table_info}"
-)
+logger.debug(
+    "destination connector engine: %s with table_info keys: %s",
+    type(engine).__name__,
+    list(table_info.keys()) if isinstance(table_info, dict) else table_info,
+)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between bb1aee0 and 3a78a37.

📒 Files selected for processing (2)
  • backend/workflow_manager/endpoint_v2/database_utils.py (1 hunks)
  • backend/workflow_manager/endpoint_v2/destination.py (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build

Comment thread backend/workflow_manager/endpoint_v2/database_utils.py

@chandrasekharan-zipstack chandrasekharan-zipstack left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've approved this PR to unblock it but I don't have much context here, do check the code rabbit comment I unresolved

@github-actions

Copy link
Copy Markdown
Contributor
filepath function $$\textcolor{#23d18b}{\tt{passed}}$$ SUBTOTAL
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_logs}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_cleanup}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_cleanup\_skip}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_client\_init}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_image\_exists}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_image}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_container\_run\_config}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_container\_run\_config\_without\_mount}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_run\_container}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_image\_for\_sidecar}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_sidecar\_container}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{TOTAL}}$$ $$\textcolor{#23d18b}{\tt{11}}$$ $$\textcolor{#23d18b}{\tt{11}}$$

@sonarqubecloud

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
backend/workflow_manager/endpoint_v2/database_utils.py (3)

167-173: DRY up column-presence checks with a tiny helper (optional).

The has_*_col predicates repeat the same pattern. A helper improves readability and keeps the logic in one place.

Apply within this block:

-            has_v2_col = (
-                (table_info is None)
-                or any(k.lower() == v2_col_name.lower() for k in table_info)
-                if table_info
-                else True
-            )
+            has_v2_col = _has_col(table_info, v2_col_name)

Add this helper inside get_columns_and_values (or as a @staticmethod) and optionally use it for metadata/error/status too:

def _has_col(table_info: dict[str, str] | None, col_name: str) -> bool:
    if not table_info:
        return True
    col_lc = col_name.lower()
    try:
        iterable = table_info.keys()
    except AttributeError:
        iterable = table_info
    return any((k or "").lower() == col_lc for k in iterable)

197-205: Docstring arg name mismatch (nit).

“connector_cls” in the docstring should be “conn_cls”.

-        Args:
-            connector_cls: DB connection class
+        Args:
+            conn_cls: DB connection class

268-268: Typo in log message (nit).

“sucessfully” → “successfully”.

-        logger.debug(f"sucessfully inserted into table {table_name} with: {sql} query")
+        logger.debug(f"successfully inserted into table {table_name} with: {sql} query")
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 3a78a37 and d51553b.

📒 Files selected for processing (1)
  • backend/workflow_manager/endpoint_v2/database_utils.py (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (1)
backend/workflow_manager/endpoint_v2/database_utils.py (1)

167-173: Guarded writes to “_v2” look correct — backward compatible.

Conditionally populating <single_column_name>_v2 based on table_info prevents inserts from failing on unmigrated tables while still creating the column on first-write (when schema is unknown/empty). Nice fix.

  • Please confirm: in our code paths, an empty table_info reliably indicates “new table to be created” rather than “schema fetch failed/insufficient privileges”. If the latter can occur, we might inadvertently attempt to write a non-existent _v2 column.

Also applies to: 177-182

Comment thread backend/workflow_manager/endpoint_v2/database_utils.py
@kirtimanmishrazipstack kirtimanmishrazipstack merged commit ffac92b into main Sep 16, 2025
7 checks passed
@kirtimanmishrazipstack kirtimanmishrazipstack deleted the UN-2808-db-connector-column-v2-fix branch September 16, 2025 08:16
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.

3 participants