dbagent-cli 0.1.4__tar.gz → 0.1.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/PKG-INFO +1 -1
  2. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/__init__.py +1 -1
  3. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/agent/generator.py +9 -3
  4. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/cli.py +36 -4
  5. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent_cli.egg-info/PKG-INFO +1 -1
  6. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/pyproject.toml +1 -1
  7. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/README.md +0 -0
  8. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/agent/pipeline.py +0 -0
  9. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/agent/validator.py +0 -0
  10. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/config.py +0 -0
  11. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/connectors/base.py +0 -0
  12. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/connectors/factory.py +0 -0
  13. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/connectors/mongo.py +0 -0
  14. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/connectors/relational.py +0 -0
  15. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/llm/auto_setup.py +0 -0
  16. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/llm/base.py +0 -0
  17. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/llm/factory.py +0 -0
  18. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/llm/gemini_provider.py +0 -0
  19. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/llm/groq_provider.py +0 -0
  20. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/llm/mock_provider.py +0 -0
  21. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/llm/ollama_provider.py +0 -0
  22. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/llm/openrouter_provider.py +0 -0
  23. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/schema/formatter.py +0 -0
  24. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/schema/models.py +0 -0
  25. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/schema/selector.py +0 -0
  26. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/ui/console.py +0 -0
  27. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent/ui/viewer.py +0 -0
  28. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent_cli.egg-info/SOURCES.txt +0 -0
  29. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent_cli.egg-info/dependency_links.txt +0 -0
  30. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent_cli.egg-info/entry_points.txt +0 -0
  31. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent_cli.egg-info/requires.txt +0 -0
  32. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/dbagent_cli.egg-info/top_level.txt +0 -0
  33. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/setup.cfg +0 -0
  34. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/tests/test_cli.py +0 -0
  35. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/tests/test_connectors.py +0 -0
  36. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/tests/test_generator.py +0 -0
  37. {dbagent_cli-0.1.4 → dbagent_cli-0.1.5}/tests/test_schema.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dbagent-cli
3
- Version: 0.1.4
3
+ Version: 0.1.5
4
4
  Summary: Universal Database Introspection and Script Generation AI Agent (CLI)
5
5
  Author: Santhosh Gupta
6
6
  Requires-Python: >=3.9
@@ -2,5 +2,5 @@
2
2
  DB-Agent: Universal Database Introspection and Script Generation AI Agent (CLI).
3
3
  """
4
4
 
5
- __version__ = "0.1.4"
5
+ __version__ = "0.1.5"
6
6
  __author__ = "Santhosh Gupta"
@@ -51,9 +51,15 @@ Generate ONLY the raw executable SQL query for the given database. No markdown f
51
51
  2. Use the exact table and column names from the schema above.
52
52
  3. Use dialect-specific syntax for `{dialect_name}`.
53
53
  4. Write clean, optimized SQL with uppercase keywords.
54
- 5. If the user asks for recent/time-based data, use the dialect's native datetime functions.
55
- 6. Always include appropriate WHERE clauses, JOINs, and ORDER BY as needed.
56
- 7. Default to LIMIT 50 unless the user specifies a count.
54
+ 5. If the user asks for recent/time-based data, use native datetime functions (e.g. for PostgreSQL: `NOW() - INTERVAL '1 hour'`, for SQLite: `datetime('now', '-1 hour')`, for MySQL: `NOW() - INTERVAL 1 HOUR`).
55
+ 6. For queries inspecting PostgreSQL foreign key mappings or table relationships via system catalog, use standard joins:
56
+ SELECT tc.table_name, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name
57
+ FROM information_schema.table_constraints tc
58
+ JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name
59
+ JOIN information_schema.constraint_column_usage ccu ON tc.constraint_name = ccu.constraint_name
60
+ WHERE tc.constraint_type = 'FOREIGN KEY';
61
+ 7. Always include appropriate WHERE clauses, JOINs, and ORDER BY as needed.
62
+ 8. Default to LIMIT 50 unless the user specifies a count.
57
63
  """
58
64
 
59
65
 
@@ -509,7 +509,7 @@ def chat_command(
509
509
  console.print(f"[bold green]Connected:[/bold green] {db_name} ({dialect}) - {len(table_names)} tables")
510
510
  console.print(f"[bold cyan]AI:[/bold cyan] {llm.name}")
511
511
  console.print("[dim]Type your question in plain English. Read queries auto-execute. Write queries ask for confirmation.[/dim]")
512
- console.print("[dim]Commands: [bold]:tables[/bold] | [bold]:table <name>[/bold] | [bold]:explain[/bold] | [bold]:history[/bold] | [bold]:auto[/bold]/[bold]:noauto[/bold] | [bold]:run[/bold] | [bold]:export <file>[/bold] | [bold]:exit[/bold][/dim]\n")
512
+ console.print("[dim]Commands: [bold]:tables[/bold] | [bold]:table <name>[/bold] | [bold]:fk <name>[/bold] | [bold]:explain[/bold] | [bold]:history[/bold] | [bold]:auto[/bold]/[bold]:noauto[/bold] | [bold]:run[/bold] | [bold]:export <file>[/bold] | [bold]:exit[/bold][/dim]\n")
513
513
 
514
514
  history_file = config_mgr.config_dir / "chat_history.txt"
515
515
  session = PromptSession(history=FileHistory(str(history_file)))
@@ -537,15 +537,47 @@ def chat_command(
537
537
 
538
538
  if user_input.startswith(":table "):
539
539
  tname = user_input.split(" ", 1)[1].strip()
540
- with console.status(f"[bold cyan]Inspecting {tname}...[/bold cyan]"):
541
- on_demand_schema = connector.inspect_schema(table_names=[tname], include_samples=True)
542
- tmodel = on_demand_schema.get_table(tname)
540
+ exact, fuzzy = connector.resolve_tables(tname)
541
+ target = exact[0] if exact else (fuzzy[0] if fuzzy else tname)
542
+ with console.status(f"[bold cyan]Inspecting {target}...[/bold cyan]"):
543
+ on_demand_schema = connector.inspect_schema(table_names=[target], include_samples=True)
544
+ tmodel = on_demand_schema.get_table(target)
543
545
  if tmodel:
544
546
  SchemaViewer.display_table_detail(tmodel)
545
547
  else:
546
548
  print_error(f"Table '{tname}' not found.")
547
549
  continue
548
550
 
551
+ if user_input.startswith(":relations ") or user_input.startswith(":fk ") or user_input.startswith(":mapped "):
552
+ tname = user_input.split(" ", 1)[1].strip()
553
+ exact, fuzzy = connector.resolve_tables(tname)
554
+ target = exact[0] if exact else (fuzzy[0] if fuzzy else tname)
555
+ with console.status(f"[bold cyan]Finding relationships for {target}...[/bold cyan]"):
556
+ full_schema = connector.inspect_schema(include_samples=False, max_samples=0)
557
+
558
+ # Find FKs where target references others, and others reference target
559
+ tmodel = full_schema.get_table(target)
560
+ outgoing = tmodel.foreign_keys if tmodel else []
561
+ incoming = []
562
+ for other in full_schema.tables:
563
+ for fk in other.foreign_keys:
564
+ if fk.referred_table.lower() == target.lower():
565
+ incoming.append((other.name, fk))
566
+
567
+ console.print(f"\n[bold cyan]Relationships mapped to table: [bold white]{target}[/bold white][/bold cyan]\n")
568
+ if outgoing:
569
+ console.print("[bold green]Outgoing (This table references):[/bold green]")
570
+ for fk in outgoing:
571
+ console.print(f" * ({', '.join(fk.constrained_columns)}) -> [bold]{fk.referred_table}[/bold]({', '.join(fk.referred_columns)})")
572
+ if incoming:
573
+ console.print("\n[bold yellow]Incoming (Other tables reference this table):[/bold yellow]")
574
+ for src_table, fk in incoming:
575
+ console.print(f" * [bold]{src_table}[/bold]({', '.join(fk.constrained_columns)}) -> ({', '.join(fk.referred_columns)})")
576
+ if not outgoing and not incoming:
577
+ console.print(f"[dim]No foreign key constraints found directly mapped to '{target}'.[/dim]")
578
+ console.print("")
579
+ continue
580
+
549
581
  if user_input.lower() == ":explain":
550
582
  if last_result and last_result.sql:
551
583
  print_code(last_result.sql, "sql", "Last Executed SQL")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dbagent-cli
3
- Version: 0.1.4
3
+ Version: 0.1.5
4
4
  Summary: Universal Database Introspection and Script Generation AI Agent (CLI)
5
5
  Author: Santhosh Gupta
6
6
  Requires-Python: >=3.9
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dbagent-cli"
7
- version = "0.1.4"
7
+ version = "0.1.5"
8
8
  description = "Universal Database Introspection and Script Generation AI Agent (CLI)"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
File without changes
File without changes