datus-snowflake 0.1.0__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.
@@ -0,0 +1,137 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ pip-wheel-metadata/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # PyInstaller
31
+ *.manifest
32
+ *.spec
33
+
34
+ # Installer logs
35
+ pip-log.txt
36
+ pip-delete-this-directory.txt
37
+
38
+ # Unit test / coverage reports
39
+ htmlcov/
40
+ .tox/
41
+ .nox/
42
+ .coverage
43
+ .coverage.*
44
+ .cache
45
+ nosetests.xml
46
+ coverage.xml
47
+ *.cover
48
+ *.py,cover
49
+ .hypothesis/
50
+ .pytest_cache/
51
+
52
+ # Translations
53
+ *.mo
54
+ *.pot
55
+
56
+ # Django stuff:
57
+ *.log
58
+ local_settings.py
59
+ db.sqlite3
60
+ db.sqlite3-journal
61
+
62
+ # Flask stuff:
63
+ instance/
64
+ .webassets-cache
65
+
66
+ # Scrapy stuff:
67
+ .scrapy
68
+
69
+ # Sphinx documentation
70
+ docs/_build/
71
+
72
+ # PyBuilder
73
+ target/
74
+
75
+ # Jupyter Notebook
76
+ .ipynb_checkpoints
77
+
78
+ # IPython
79
+ profile_default/
80
+ ipython_config.py
81
+
82
+ # pyenv
83
+ .python-version
84
+
85
+ # pipenv
86
+ Pipfile.lock
87
+
88
+ # uv
89
+ uv.lock
90
+
91
+ # PEP 582
92
+ __pypackages__/
93
+
94
+ # Celery stuff
95
+ celerybeat-schedule
96
+ celerybeat.pid
97
+
98
+ # SageMath parsed files
99
+ *.sage.py
100
+
101
+ # Environments
102
+ .env
103
+ .venv
104
+ env/
105
+ venv/
106
+ ENV/
107
+ env.bak/
108
+ venv.bak/
109
+
110
+ # Spyder project settings
111
+ .spyderproject
112
+ .spyproject
113
+
114
+ # Rope project settings
115
+ .ropeproject
116
+
117
+ # mkdocs documentation
118
+ /site
119
+
120
+ # mypy
121
+ .mypy_cache/
122
+ .dmypy.json
123
+ dmypy.json
124
+
125
+ # Pyre type checker
126
+ .pyre/
127
+
128
+ # IDEs
129
+ .vscode/
130
+ .idea/
131
+ *.swp
132
+ *.swo
133
+ *~
134
+
135
+ # OS
136
+ .DS_Store
137
+ Thumbs.db
@@ -0,0 +1,238 @@
1
+ Metadata-Version: 2.4
2
+ Name: datus-snowflake
3
+ Version: 0.1.0
4
+ Summary: Snowflake adapter for Datus Agent
5
+ Author-email: DatusAI <support@datus.ai>
6
+ License: Apache-2.0
7
+ Requires-Python: >=3.8
8
+ Requires-Dist: datus-agent>0.2.1
9
+ Requires-Dist: snowflake-connector-python>=3.6.0
10
+ Provides-Extra: dev
11
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
12
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
13
+ Description-Content-Type: text/markdown
14
+
15
+ # Datus Snowflake Adapter
16
+
17
+ Snowflake database adapter for Datus Agent, providing native Snowflake connector support.
18
+
19
+ ## Features
20
+
21
+ - **Native Snowflake SDK**: Uses `snowflake-connector-python` for optimal performance
22
+ - **Full Snowflake Support**: Databases, schemas, tables, views, and materialized views
23
+ - **Efficient Metadata Retrieval**: Uses SHOW commands for fast metadata queries
24
+ - **Arrow-based Execution**: High-performance query execution with Apache Arrow
25
+ - **Multiple Result Formats**: CSV, Pandas DataFrame, Arrow Table, and Python list
26
+ - **Complete CRUD Operations**: INSERT, UPDATE, DELETE, and DDL support
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ pip install datus-snowflake
32
+ ```
33
+
34
+ This will automatically install the required dependencies:
35
+ - `datus-agent>=0.3.0`
36
+ - `snowflake-connector-python>=3.6.0`
37
+
38
+ ## Usage
39
+
40
+ ### Basic Connection
41
+
42
+ ```python
43
+ from datus_snowflake import SnowflakeConnector
44
+
45
+ # Create connector
46
+ connector = SnowflakeConnector(
47
+ account="myaccount",
48
+ user="myuser",
49
+ password="mypassword",
50
+ warehouse="my_warehouse",
51
+ database="my_database",
52
+ schema="my_schema"
53
+ )
54
+
55
+ # Test connection
56
+ result = connector.test_connection()
57
+ print(result) # {'success': True, 'message': 'Connection successful', 'databases': ''}
58
+ ```
59
+
60
+ ### Execute Queries
61
+
62
+ ```python
63
+ # Execute query and get CSV result
64
+ result = connector.execute_query("SELECT * FROM users LIMIT 10")
65
+ print(result.sql_return) # CSV string
66
+
67
+ # Execute query and get pandas DataFrame
68
+ result = connector.execute_query("SELECT * FROM users LIMIT 10", result_format="pandas")
69
+ df = result.sql_return
70
+ print(df.head())
71
+
72
+ # Execute query and get Arrow table
73
+ result = connector.execute_query("SELECT * FROM users LIMIT 10", result_format="arrow")
74
+ arrow_table = result.sql_return
75
+ print(arrow_table.schema)
76
+ ```
77
+
78
+ ### Metadata Operations
79
+
80
+ ```python
81
+ # Get databases
82
+ databases = connector.get_databases()
83
+ print(f"Databases: {databases}")
84
+
85
+ # Get schemas
86
+ schemas = connector.get_schemas(database_name="my_database")
87
+ print(f"Schemas: {schemas}")
88
+
89
+ # Get tables
90
+ tables = connector.get_tables(database_name="my_database", schema_name="public")
91
+ print(f"Tables: {tables}")
92
+
93
+ # Get views
94
+ views = connector.get_views(database_name="my_database", schema_name="public")
95
+ print(f"Views: {views}")
96
+
97
+ # Get materialized views
98
+ mvs = connector.get_materialized_views(database_name="my_database", schema_name="public")
99
+ print(f"Materialized Views: {mvs}")
100
+ ```
101
+
102
+ ### Get Table Schema
103
+
104
+ ```python
105
+ # Get table structure
106
+ schema = connector.get_schema(
107
+ database_name="my_database",
108
+ schema_name="public",
109
+ table_name="users"
110
+ )
111
+
112
+ for column in schema[:-1]: # Last item is table metadata
113
+ print(f"{column['name']}: {column['type']} (nullable: {column['nullable']})")
114
+ ```
115
+
116
+ ### Get DDL Definitions
117
+
118
+ ```python
119
+ # Get tables with DDL
120
+ tables_with_ddl = connector.get_tables_with_ddl(
121
+ database_name="my_database",
122
+ schema_name="public"
123
+ )
124
+
125
+ for table in tables_with_ddl:
126
+ print(f"\nTable: {table['table_name']}")
127
+ print(f"DDL:\n{table['definition']}")
128
+
129
+ # Get views with DDL
130
+ views_with_ddl = connector.get_views_with_ddl(
131
+ database_name="my_database",
132
+ schema_name="public"
133
+ )
134
+
135
+ # Get materialized views with DDL
136
+ mvs_with_ddl = connector.get_materialized_views_with_ddl(
137
+ database_name="my_database",
138
+ schema_name="public"
139
+ )
140
+ ```
141
+
142
+ ### Get Sample Data
143
+
144
+ ```python
145
+ # Get sample rows from specific tables
146
+ samples = connector.get_sample_rows(
147
+ tables=["users", "orders"],
148
+ top_n=5,
149
+ database_name="my_database",
150
+ schema_name="public"
151
+ )
152
+
153
+ for sample in samples:
154
+ print(f"\nTable: {sample['table_name']}")
155
+ print(sample['sample_rows']) # CSV format
156
+ ```
157
+
158
+ ### CRUD Operations
159
+
160
+ ```python
161
+ # INSERT
162
+ result = connector.execute_insert(
163
+ "INSERT INTO users (name, email) VALUES ('John', 'john@example.com')"
164
+ )
165
+ print(f"Inserted rows: {result.row_count}")
166
+
167
+ # UPDATE
168
+ result = connector.execute_update(
169
+ "UPDATE users SET email = 'newemail@example.com' WHERE name = 'John'"
170
+ )
171
+ print(f"Updated rows: {result.row_count}")
172
+
173
+ # DELETE
174
+ result = connector.execute_delete(
175
+ "DELETE FROM users WHERE name = 'John'"
176
+ )
177
+ print(f"Deleted rows: {result.row_count}")
178
+
179
+ # DDL
180
+ result = connector.execute_ddl(
181
+ "CREATE TABLE test_table (id INT, name VARCHAR(100))"
182
+ )
183
+ print(f"DDL executed: {result.success}")
184
+ ```
185
+
186
+ ### Context Switching
187
+
188
+ ```python
189
+ # Switch database
190
+ connector.do_switch_context(database_name="another_database")
191
+
192
+ # Switch schema
193
+ connector.do_switch_context(
194
+ database_name="my_database",
195
+ schema_name="another_schema"
196
+ )
197
+ ```
198
+
199
+ ## Configuration with Datus Agent
200
+
201
+ When using with Datus Agent, the adapter is automatically discovered via entry points:
202
+
203
+ ```yaml
204
+ # config.yaml
205
+ database:
206
+ type: snowflake
207
+ account: myaccount
208
+ username: myuser
209
+ password: mypassword
210
+ warehouse: my_warehouse
211
+ database: my_database
212
+ schema: my_schema
213
+ ```
214
+
215
+ The adapter will be automatically loaded when you use `type: snowflake`.
216
+
217
+ ## Architecture
218
+
219
+ This adapter:
220
+ - Inherits from `BaseSqlConnector` in `datus-agent`
221
+ - Uses native Snowflake connector for optimal performance
222
+ - Implements all required abstract methods
223
+ - Provides Snowflake-specific optimizations (SHOW commands, Arrow format)
224
+
225
+ ## Development
226
+
227
+ ```bash
228
+ # Install in development mode
229
+ cd datus-snowflake
230
+ pip install -e .
231
+
232
+ # Run tests
233
+ pytest tests/
234
+ ```
235
+
236
+ ## License
237
+
238
+ Apache License 2.0
@@ -0,0 +1,224 @@
1
+ # Datus Snowflake Adapter
2
+
3
+ Snowflake database adapter for Datus Agent, providing native Snowflake connector support.
4
+
5
+ ## Features
6
+
7
+ - **Native Snowflake SDK**: Uses `snowflake-connector-python` for optimal performance
8
+ - **Full Snowflake Support**: Databases, schemas, tables, views, and materialized views
9
+ - **Efficient Metadata Retrieval**: Uses SHOW commands for fast metadata queries
10
+ - **Arrow-based Execution**: High-performance query execution with Apache Arrow
11
+ - **Multiple Result Formats**: CSV, Pandas DataFrame, Arrow Table, and Python list
12
+ - **Complete CRUD Operations**: INSERT, UPDATE, DELETE, and DDL support
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install datus-snowflake
18
+ ```
19
+
20
+ This will automatically install the required dependencies:
21
+ - `datus-agent>=0.3.0`
22
+ - `snowflake-connector-python>=3.6.0`
23
+
24
+ ## Usage
25
+
26
+ ### Basic Connection
27
+
28
+ ```python
29
+ from datus_snowflake import SnowflakeConnector
30
+
31
+ # Create connector
32
+ connector = SnowflakeConnector(
33
+ account="myaccount",
34
+ user="myuser",
35
+ password="mypassword",
36
+ warehouse="my_warehouse",
37
+ database="my_database",
38
+ schema="my_schema"
39
+ )
40
+
41
+ # Test connection
42
+ result = connector.test_connection()
43
+ print(result) # {'success': True, 'message': 'Connection successful', 'databases': ''}
44
+ ```
45
+
46
+ ### Execute Queries
47
+
48
+ ```python
49
+ # Execute query and get CSV result
50
+ result = connector.execute_query("SELECT * FROM users LIMIT 10")
51
+ print(result.sql_return) # CSV string
52
+
53
+ # Execute query and get pandas DataFrame
54
+ result = connector.execute_query("SELECT * FROM users LIMIT 10", result_format="pandas")
55
+ df = result.sql_return
56
+ print(df.head())
57
+
58
+ # Execute query and get Arrow table
59
+ result = connector.execute_query("SELECT * FROM users LIMIT 10", result_format="arrow")
60
+ arrow_table = result.sql_return
61
+ print(arrow_table.schema)
62
+ ```
63
+
64
+ ### Metadata Operations
65
+
66
+ ```python
67
+ # Get databases
68
+ databases = connector.get_databases()
69
+ print(f"Databases: {databases}")
70
+
71
+ # Get schemas
72
+ schemas = connector.get_schemas(database_name="my_database")
73
+ print(f"Schemas: {schemas}")
74
+
75
+ # Get tables
76
+ tables = connector.get_tables(database_name="my_database", schema_name="public")
77
+ print(f"Tables: {tables}")
78
+
79
+ # Get views
80
+ views = connector.get_views(database_name="my_database", schema_name="public")
81
+ print(f"Views: {views}")
82
+
83
+ # Get materialized views
84
+ mvs = connector.get_materialized_views(database_name="my_database", schema_name="public")
85
+ print(f"Materialized Views: {mvs}")
86
+ ```
87
+
88
+ ### Get Table Schema
89
+
90
+ ```python
91
+ # Get table structure
92
+ schema = connector.get_schema(
93
+ database_name="my_database",
94
+ schema_name="public",
95
+ table_name="users"
96
+ )
97
+
98
+ for column in schema[:-1]: # Last item is table metadata
99
+ print(f"{column['name']}: {column['type']} (nullable: {column['nullable']})")
100
+ ```
101
+
102
+ ### Get DDL Definitions
103
+
104
+ ```python
105
+ # Get tables with DDL
106
+ tables_with_ddl = connector.get_tables_with_ddl(
107
+ database_name="my_database",
108
+ schema_name="public"
109
+ )
110
+
111
+ for table in tables_with_ddl:
112
+ print(f"\nTable: {table['table_name']}")
113
+ print(f"DDL:\n{table['definition']}")
114
+
115
+ # Get views with DDL
116
+ views_with_ddl = connector.get_views_with_ddl(
117
+ database_name="my_database",
118
+ schema_name="public"
119
+ )
120
+
121
+ # Get materialized views with DDL
122
+ mvs_with_ddl = connector.get_materialized_views_with_ddl(
123
+ database_name="my_database",
124
+ schema_name="public"
125
+ )
126
+ ```
127
+
128
+ ### Get Sample Data
129
+
130
+ ```python
131
+ # Get sample rows from specific tables
132
+ samples = connector.get_sample_rows(
133
+ tables=["users", "orders"],
134
+ top_n=5,
135
+ database_name="my_database",
136
+ schema_name="public"
137
+ )
138
+
139
+ for sample in samples:
140
+ print(f"\nTable: {sample['table_name']}")
141
+ print(sample['sample_rows']) # CSV format
142
+ ```
143
+
144
+ ### CRUD Operations
145
+
146
+ ```python
147
+ # INSERT
148
+ result = connector.execute_insert(
149
+ "INSERT INTO users (name, email) VALUES ('John', 'john@example.com')"
150
+ )
151
+ print(f"Inserted rows: {result.row_count}")
152
+
153
+ # UPDATE
154
+ result = connector.execute_update(
155
+ "UPDATE users SET email = 'newemail@example.com' WHERE name = 'John'"
156
+ )
157
+ print(f"Updated rows: {result.row_count}")
158
+
159
+ # DELETE
160
+ result = connector.execute_delete(
161
+ "DELETE FROM users WHERE name = 'John'"
162
+ )
163
+ print(f"Deleted rows: {result.row_count}")
164
+
165
+ # DDL
166
+ result = connector.execute_ddl(
167
+ "CREATE TABLE test_table (id INT, name VARCHAR(100))"
168
+ )
169
+ print(f"DDL executed: {result.success}")
170
+ ```
171
+
172
+ ### Context Switching
173
+
174
+ ```python
175
+ # Switch database
176
+ connector.do_switch_context(database_name="another_database")
177
+
178
+ # Switch schema
179
+ connector.do_switch_context(
180
+ database_name="my_database",
181
+ schema_name="another_schema"
182
+ )
183
+ ```
184
+
185
+ ## Configuration with Datus Agent
186
+
187
+ When using with Datus Agent, the adapter is automatically discovered via entry points:
188
+
189
+ ```yaml
190
+ # config.yaml
191
+ database:
192
+ type: snowflake
193
+ account: myaccount
194
+ username: myuser
195
+ password: mypassword
196
+ warehouse: my_warehouse
197
+ database: my_database
198
+ schema: my_schema
199
+ ```
200
+
201
+ The adapter will be automatically loaded when you use `type: snowflake`.
202
+
203
+ ## Architecture
204
+
205
+ This adapter:
206
+ - Inherits from `BaseSqlConnector` in `datus-agent`
207
+ - Uses native Snowflake connector for optimal performance
208
+ - Implements all required abstract methods
209
+ - Provides Snowflake-specific optimizations (SHOW commands, Arrow format)
210
+
211
+ ## Development
212
+
213
+ ```bash
214
+ # Install in development mode
215
+ cd datus-snowflake
216
+ pip install -e .
217
+
218
+ # Run tests
219
+ pytest tests/
220
+ ```
221
+
222
+ ## License
223
+
224
+ Apache License 2.0
@@ -0,0 +1,18 @@
1
+ """Snowflake adapter for Datus Agent."""
2
+
3
+ from datus.tools.db_tools import connector_registry
4
+
5
+ from .config import SnowflakeConfig
6
+ from .connector import SnowflakeConnector
7
+
8
+ __version__ = "0.1.0"
9
+ __all__ = ["SnowflakeConnector", "SnowflakeConfig", "register"]
10
+
11
+
12
+ def register():
13
+ """Register Snowflake connector with Datus registry."""
14
+ connector_registry.register("snowflake", SnowflakeConnector)
15
+
16
+
17
+ # Auto-register when imported
18
+ register()
@@ -0,0 +1,22 @@
1
+ # Copyright 2025-present DatusAI, Inc.
2
+ # Licensed under the Apache License, Version 2.0.
3
+ # See http://www.apache.org/licenses/LICENSE-2.0 for details.
4
+
5
+ from typing import Optional
6
+
7
+ from pydantic import BaseModel, ConfigDict, Field
8
+
9
+
10
+ class SnowflakeConfig(BaseModel):
11
+ """Snowflake-specific configuration."""
12
+
13
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
14
+
15
+ account: str = Field(..., description="Snowflake account identifier")
16
+ username: str = Field(..., description="Snowflake username")
17
+ password: str = Field(..., description="Snowflake password")
18
+ warehouse: str = Field(..., description="Snowflake warehouse name")
19
+ database: Optional[str] = Field(default=None, description="Default database name")
20
+ schema_name: Optional[str] = Field(default=None, alias="schema", description="Default schema name")
21
+ role: Optional[str] = Field(default=None, description="Snowflake role to use")
22
+ timeout_seconds: int = Field(default=30, description="Connection timeout in seconds")