Skip to content

fix: create or drop view #349

Merged
Ryuk-me merged 1 commit into
datachecks:mainfrom
Ryuk-me:view_create_drop
Nov 21, 2025
Merged

fix: create or drop view #349
Ryuk-me merged 1 commit into
datachecks:mainfrom
Ryuk-me:view_create_drop

Conversation

@Ryuk-me

@Ryuk-me Ryuk-me commented Nov 21, 2025

Copy link
Copy Markdown
Member

Summary by CodeRabbit

Version 0.9.8

  • New Features

    • Added dynamic SQL view management capabilities: create, drop, and generate view names across datasources
    • Extended BigQuery support with view creation and dropping functionality
    • Improved view name generation for Oracle database compatibility
  • Chores

    • Bumped version to 0.9.8

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Nov 21, 2025

Copy link
Copy Markdown

Walkthrough

The pull request bumps the package version to 0.9.8 and introduces view management utilities across multiple datasource integrations. New methods enable dynamic SQL view creation, deletion, and name generation for SQL, BigQuery, and Oracle datasources, supporting both SQLAlchemy and native connections with error handling.

Changes

Cohort / File(s) Summary
Version Bump
dcs_core/__version__.py, pyproject.toml
Updated package version from 0.9.7 to 0.9.8 across version metadata files
SQL DataSource View Utilities
dcs_core/core/datasource/sql_datasource.py
Added imports (secrets, string, time) and three new public methods: generate_view_name() for unique view naming, create_view() for SQL view creation with Connection/Engine support, and drop_view() for view deletion with transaction handling and error logging
BigQuery View Management
dcs_core/integrations/databases/bigquery.py
Added two new public methods: create_view() to build and execute CREATE VIEW queries with fallback dummy views, and drop_view() to execute DROP VIEW queries, both with error logging
Oracle View Naming
dcs_core/integrations/databases/oracle.py
Added generate_view_name() method to generate or format view names with timestamp-based prefixes and random suffixes, with newly imported secrets, string, and time modules

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

  • sql_datasource.py: Focus on connection/engine handling logic, transaction semantics, and error handling paths for both SQLAlchemy and fallback cases
  • BigQuery/Oracle integrations: Straightforward new methods with query execution and naming logic
  • Version files: Trivial string updates

Possibly related PRs

Suggested labels

Review effort 1/5

Suggested reviewers

  • rishav2803
  • Kanai2003

Poem

🐰 A view to behold, we hop and we play,
Dynamic view names, they're here to stay,
BigQuery, Oracle, SQL so fine,
Version eight-point-nine, a release divine! 🌟

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is entirely missing, containing no information about fixes, implementation details, testing, or any required template sections. Add a complete pull request description following the repository template, including issue reference, detailed summary, type of change checkbox, and testing information.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'fix: create or drop view' is somewhat vague; while it mentions the main features added (creating/dropping views), it doesn't clearly specify what is being fixed or which database systems are involved. Consider a more specific title like 'feat: add view creation and deletion methods for SQL datasources' to better reflect that these are new features across multiple database integrations.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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.

@Ryuk-me Ryuk-me merged commit a0cd368 into datachecks:main Nov 21, 2025
4 of 7 checks passed
@Ryuk-me Ryuk-me deleted the view_create_drop branch November 21, 2025 12:08

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 (2)
dcs_core/core/datasource/sql_datasource.py (1)

1053-1136: View helpers are generally solid; consider small API & robustness tweaks

The new generate_view_name, create_view, and drop_view implementations look correct and cover SQLAlchemy Engine/Connection as well as plain DB‑API style connections. A couple of small improvements to consider:

  1. Guard against missing connection explicitly

Right now, if self.connection is None, the logic falls through to the generic branch and eventually hits self.connection.execute(...), yielding an AttributeError that gets caught and logged as a generic “Error creating/dropping view …” message.

You could fail fast with a clearer error:

     def create_view(
         self,
         query: str | None = None,
         schema: str | None = None,
         view_name: str | None = None,
     ) -> str | None:
+        if self.connection is None:
+            logger.error("Cannot create view because no connection is established.")
+            return None

and similarly for drop_view.

  1. Make schema optional in drop_view for API symmetry

create_view treats schema as optional, but drop_view currently requires it:

def drop_view(self, view_name: str, schema: str | None) -> bool:

For a smoother caller experience and to mirror create_view, you might want:

-    def drop_view(self, view_name: str, schema: str | None) -> bool:
+    def drop_view(self, view_name: str, schema: str | None = None) -> bool:

so callers don’t have to remember different defaults between create and drop.

dcs_core/integrations/databases/oracle.py (1)

15-17: Oracle generate_view_name behavior is correct; minor cleanup possible

The override correctly enforces uppercase view names for Oracle, and the generated name length stays within Oracle’s identifier limits. One small readability tweak:

random_string = "".join(
    secrets.choice(string.ascii_letters + string.digits) for _ in range(8)
)
timestamp = int(time.time())
return f"dcs_view_{timestamp}_{random_string.lower()}".upper()

The .lower() followed by .upper() on the whole string is redundant. You could simplify to:

-        random_string = "".join(
-            secrets.choice(string.ascii_letters + string.digits) for _ in range(8)
-        )
-        timestamp = int(time.time())
-        return f"dcs_view_{timestamp}_{random_string.lower()}".upper()
+        random_string = "".join(
+            secrets.choice(string.ascii_letters + string.digits) for _ in range(8)
+        )
+        timestamp = int(time.time())
+        return f"DCS_VIEW_{timestamp}_{random_string}"

Functionality stays the same but the intent is clearer.

Also applies to: 697-704

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7491303 and d9a4ae0.

📒 Files selected for processing (5)
  • dcs_core/__version__.py (1 hunks)
  • dcs_core/core/datasource/sql_datasource.py (2 hunks)
  • dcs_core/integrations/databases/bigquery.py (2 hunks)
  • dcs_core/integrations/databases/oracle.py (2 hunks)
  • pyproject.toml (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
dcs_core/core/datasource/sql_datasource.py (4)
dcs_core/integrations/databases/oracle.py (2)
  • generate_view_name (697-704)
  • connect (47-71)
dcs_core/integrations/databases/bigquery.py (3)
  • create_view (166-191)
  • connect (37-75)
  • drop_view (193-205)
dcs_core/integrations/databases/mysql.py (1)
  • connect (43-74)
dcs_core/integrations/databases/postgres.py (1)
  • connect (33-57)
dcs_core/integrations/databases/bigquery.py (2)
dcs_core/core/datasource/sql_datasource.py (3)
  • create_view (1063-1105)
  • generate_view_name (1054-1061)
  • drop_view (1107-1136)
dcs_core/integrations/databases/oracle.py (1)
  • generate_view_name (697-704)
dcs_core/integrations/databases/oracle.py (1)
dcs_core/core/datasource/sql_datasource.py (1)
  • generate_view_name (1054-1061)
🪛 Ruff (0.14.5)
dcs_core/core/datasource/sql_datasource.py

1088-1089: try-except-pass detected, consider logging the exception

(S110)


1088-1088: Do not catch blind exception: Exception

(BLE001)


1097-1098: try-except-pass detected, consider logging the exception

(S110)


1097-1097: Do not catch blind exception: Exception

(BLE001)


1102-1102: Consider moving this statement to an else block

(TRY300)


1103-1103: Do not catch blind exception: Exception

(BLE001)


1121-1122: try-except-pass detected, consider logging the exception

(S110)


1121-1121: Do not catch blind exception: Exception

(BLE001)


1129-1130: try-except-pass detected, consider logging the exception

(S110)


1129-1129: Do not catch blind exception: Exception

(BLE001)


1133-1133: Consider moving this statement to an else block

(TRY300)


1134-1134: Do not catch blind exception: Exception

(BLE001)

dcs_core/integrations/databases/bigquery.py

189-189: Do not catch blind exception: Exception

(BLE001)


202-202: Consider moving this statement to an else block

(TRY300)


203-203: Do not catch blind exception: Exception

(BLE001)

🔇 Additional comments (2)
pyproject.toml (1)

3-3: Version bump looks consistent

Version updated to 0.9.8 here and matches dcs_core/__version__.__version__; no issues from this change.

dcs_core/__version__.py (1)

15-15: Public version constant correctly updated

__version__ = "0.9.8" matches the project metadata; this is good to go.

Comment on lines +166 to +205
def create_view(
self,
query: Optional[str] = None,
dataset: Optional[str] = None,
view_name: Optional[str] = None,
) -> str | None:
view_name = self.generate_view_name(view_name=view_name)
full_name = (
f"`{self.project}`.`{dataset}`.`{view_name}`"
if dataset
else f"`{view_name}`"
)
try:
if query is None:
create_view_query = (
f"CREATE VIEW {full_name} AS SELECT 1 AS dummy_column WHERE FALSE"
)
self.connection.execute(create_view_query)
return full_name
else:
create_view_query = f"CREATE VIEW {full_name} AS {query}"
self.connection.execute(create_view_query)
return full_name
except Exception as e:
logger.error(f"Error creating view: {e}")
return None

def drop_view(self, view_name: str, dataset: Optional[str] = None) -> bool:
full_name = (
f"`{self.project}`.`{dataset}`.`{view_name}`"
if dataset
else f"`{view_name}`"
)
try:
drop_view_query = f"DROP VIEW {full_name}"
self.connection.execute(drop_view_query)
return True
except Exception as e:
logger.error(f"Error dropping view: {e}")
return False

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Bug: self.project does not exist; use self.project_id (and optionally default dataset)

In both create_view and drop_view, full_name is built using self.project:

full_name = (
    f"`{self.project}`.`{dataset}`.`{view_name}`"
    if dataset
    else f"`{view_name}`"
)

But in __init__, the attribute is named self.project_id, not self.project:

self.project_id = self.data_connection.get("project")

At runtime this will raise AttributeError: 'BigQueryDataSource' object has no attribute 'project', causing all view operations to fail.

You likely want:

-        view_name = self.generate_view_name(view_name=view_name)
-        full_name = (
-            f"`{self.project}`.`{dataset}`.`{view_name}`"
-            if dataset
-            else f"`{view_name}`"
-        )
+        view_name = self.generate_view_name(view_name=view_name)
+        dataset = dataset or self.dataset_id
+        full_name = (
+            f"`{self.project_id}`.`{dataset}`.`{view_name}`"
+            if dataset
+            else f"`{view_name}`"
+        )

and similarly for drop_view:

-        full_name = (
-            f"`{self.project}`.`{dataset}`.`{view_name}`"
-            if dataset
-            else f"`{view_name}`"
-        )
+        dataset = dataset or self.dataset_id
+        full_name = (
+            f"`{self.project_id}`.`{dataset}`.`{view_name}`"
+            if dataset
+            else f"`{view_name}`"
+        )

This both fixes the missing‑attribute bug and makes the optional dataset argument fall back to the configured default, which is more ergonomic for callers.

🧰 Tools
🪛 Ruff (0.14.5)

189-189: Do not catch blind exception: Exception

(BLE001)


202-202: Consider moving this statement to an else block

(TRY300)


203-203: Do not catch blind exception: Exception

(BLE001)

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.

2 participants