pymnemon 0.1.1__py3-none-any.whl
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.
- mnemon/__init__.py +10 -0
- mnemon/db_connect.py +752 -0
- mnemon/utils/__init__.py +0 -0
- mnemon/utils/databricks_engine.py +165 -0
- mnemon/utils/dialect_queries.py +374 -0
- mnemon/utils/error_handling.py +180 -0
- pymnemon-0.1.1.dist-info/METADATA +220 -0
- pymnemon-0.1.1.dist-info/RECORD +11 -0
- pymnemon-0.1.1.dist-info/WHEEL +5 -0
- pymnemon-0.1.1.dist-info/licenses/LICENSE +21 -0
- pymnemon-0.1.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Connection error normalization for user-friendly feedback.
|
|
3
|
+
Maps database-specific errors to actionable messages.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from enum import Enum
|
|
7
|
+
from typing import Optional
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
import re
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ErrorCategory(Enum):
|
|
13
|
+
AUTH_FAILED = "auth_failed"
|
|
14
|
+
NETWORK_UNREACHABLE = "network_unreachable"
|
|
15
|
+
DATABASE_NOT_FOUND = "database_not_found"
|
|
16
|
+
SCHEMA_NOT_FOUND = "schema_not_found"
|
|
17
|
+
TABLE_NOT_FOUND = "table_not_found"
|
|
18
|
+
PERMISSION_DENIED = "permission_denied"
|
|
19
|
+
SSL_ERROR = "ssl_error"
|
|
20
|
+
TIMEOUT = "timeout"
|
|
21
|
+
INVALID_CONFIG = "invalid_config"
|
|
22
|
+
UNKNOWN = "unknown"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass
|
|
26
|
+
class NormalizedError:
|
|
27
|
+
category: ErrorCategory
|
|
28
|
+
message: str
|
|
29
|
+
next_steps: list[str]
|
|
30
|
+
original_error: str
|
|
31
|
+
field_hint: Optional[str] = None # Which form field is likely wrong
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# Error patterns per database
|
|
35
|
+
ERROR_PATTERNS = {
|
|
36
|
+
"postgresql": [
|
|
37
|
+
(r"password authentication failed", ErrorCategory.AUTH_FAILED, ["Verify username and password", "Ensure user exists in PostgreSQL"]),
|
|
38
|
+
(r"could not connect to server.*Connection refused", ErrorCategory.NETWORK_UNREACHABLE, ["Verify host and port", "Check if PostgreSQL is running", "Check firewall rules"]),
|
|
39
|
+
(r"database .* does not exist", ErrorCategory.DATABASE_NOT_FOUND, ["Verify database name", "Check spelling"]),
|
|
40
|
+
(r"SSL.*certificate", ErrorCategory.SSL_ERROR, ["Verify SSL certificate paths", "Check certificate validity"]),
|
|
41
|
+
(r"permission denied", ErrorCategory.PERMISSION_DENIED, ["Check user privileges", "Contact database administrator"]),
|
|
42
|
+
(r"timeout", ErrorCategory.TIMEOUT, ["Check network connectivity", "Increase timeout settings"]),
|
|
43
|
+
],
|
|
44
|
+
|
|
45
|
+
"snowflake": [
|
|
46
|
+
(r"Incorrect username or password", ErrorCategory.AUTH_FAILED, ["Verify username and password", "Check account identifier format"]),
|
|
47
|
+
(r"JWT token is invalid", ErrorCategory.AUTH_FAILED, ["Verify private key matches public key in Snowflake", "Check key pair configuration"]),
|
|
48
|
+
(r"account .* does not exist", ErrorCategory.INVALID_CONFIG, ["Verify account identifier", "Include region if required (e.g., xy12345.us-east-1)"]),
|
|
49
|
+
(r"Warehouse .* does not exist", ErrorCategory.INVALID_CONFIG, ["Verify warehouse name", "Check warehouse is created and accessible"]),
|
|
50
|
+
(r"Database .* does not exist", ErrorCategory.DATABASE_NOT_FOUND, ["Verify database name", "Check user has access to database"]),
|
|
51
|
+
(r"IP .* is not allowed", ErrorCategory.NETWORK_UNREACHABLE, ["Add your IP to Snowflake network policy", "Contact Snowflake administrator"]),
|
|
52
|
+
],
|
|
53
|
+
|
|
54
|
+
"bigquery": [
|
|
55
|
+
(r"Could not deserialize key data", ErrorCategory.AUTH_FAILED, ["Verify service account JSON is valid", "Re-download credentials from GCP Console"]),
|
|
56
|
+
(r"403.*Access Denied", ErrorCategory.PERMISSION_DENIED, ["Verify service account has BigQuery permissions", "Check IAM roles in GCP Console"]),
|
|
57
|
+
(r"404.*Not found: Project", ErrorCategory.INVALID_CONFIG, ["Verify project ID", "Check project exists and is accessible"]),
|
|
58
|
+
(r"404.*Not found: Dataset", ErrorCategory.SCHEMA_NOT_FOUND, ["Verify dataset name", "Check dataset exists in project"]),
|
|
59
|
+
],
|
|
60
|
+
|
|
61
|
+
"redshift": [
|
|
62
|
+
(r"password authentication failed", ErrorCategory.AUTH_FAILED, ["Verify username and password", "Ensure user exists in Redshift"]),
|
|
63
|
+
(r"could not connect to server", ErrorCategory.NETWORK_UNREACHABLE, ["Verify cluster endpoint", "Check VPC security groups", "Ensure cluster is publicly accessible or VPN is connected"]),
|
|
64
|
+
(r"database .* does not exist", ErrorCategory.DATABASE_NOT_FOUND, ["Verify database name"]),
|
|
65
|
+
],
|
|
66
|
+
|
|
67
|
+
"mysql": [
|
|
68
|
+
(r"Access denied for user", ErrorCategory.AUTH_FAILED, ["Verify username and password", "Check user host permissions"]),
|
|
69
|
+
(r"Can't connect to MySQL server", ErrorCategory.NETWORK_UNREACHABLE, ["Verify host and port", "Check if MySQL is running"]),
|
|
70
|
+
(r"Unknown database", ErrorCategory.DATABASE_NOT_FOUND, ["Verify database name"]),
|
|
71
|
+
(r"SSL connection error", ErrorCategory.SSL_ERROR, ["Verify SSL certificate paths", "Check certificate validity"]),
|
|
72
|
+
],
|
|
73
|
+
|
|
74
|
+
"clickhouse": [
|
|
75
|
+
(r"Authentication failed", ErrorCategory.AUTH_FAILED, ["Verify username and password"]),
|
|
76
|
+
(r"Connection refused", ErrorCategory.NETWORK_UNREACHABLE, ["Verify host and port", "Check if ClickHouse is running"]),
|
|
77
|
+
(r"Database .* doesn't exist", ErrorCategory.DATABASE_NOT_FOUND, ["Verify database name"]),
|
|
78
|
+
],
|
|
79
|
+
|
|
80
|
+
"databricks": [
|
|
81
|
+
(r"Invalid access token", ErrorCategory.AUTH_FAILED, ["Generate new Personal Access Token in Databricks", "Verify token has not expired"]),
|
|
82
|
+
(r"Could not resolve host", ErrorCategory.NETWORK_UNREACHABLE, ["Verify workspace URL", "Check network connectivity"]),
|
|
83
|
+
(r"HTTP 404", ErrorCategory.INVALID_CONFIG, ["Verify HTTP path for SQL warehouse", "Check warehouse exists"]),
|
|
84
|
+
],
|
|
85
|
+
|
|
86
|
+
"athena": [
|
|
87
|
+
(r"InvalidAccessKeyId", ErrorCategory.AUTH_FAILED, ["Verify AWS access key ID"]),
|
|
88
|
+
(r"SignatureDoesNotMatch", ErrorCategory.AUTH_FAILED, ["Verify AWS secret access key"]),
|
|
89
|
+
(r"Access Denied", ErrorCategory.PERMISSION_DENIED, ["Check IAM permissions for Athena and S3", "Verify S3 staging directory access"]),
|
|
90
|
+
(r"Database .* not found", ErrorCategory.DATABASE_NOT_FOUND, ["Verify schema/database name in Glue catalog"]),
|
|
91
|
+
],
|
|
92
|
+
|
|
93
|
+
# Default patterns for databases without specific patterns
|
|
94
|
+
"_default": [
|
|
95
|
+
(r"authentication|password|credential|login failed", ErrorCategory.AUTH_FAILED, ["Verify username and password"]),
|
|
96
|
+
(r"connection refused|could not connect|unreachable|host", ErrorCategory.NETWORK_UNREACHABLE, ["Verify host and port", "Check network connectivity"]),
|
|
97
|
+
(r"database.*not exist|unknown database", ErrorCategory.DATABASE_NOT_FOUND, ["Verify database name"]),
|
|
98
|
+
(r"permission denied|access denied|not authorized", ErrorCategory.PERMISSION_DENIED, ["Check user permissions"]),
|
|
99
|
+
(r"ssl|certificate|tls", ErrorCategory.SSL_ERROR, ["Check SSL configuration"]),
|
|
100
|
+
(r"timeout|timed out", ErrorCategory.TIMEOUT, ["Check network connectivity", "Increase timeout"]),
|
|
101
|
+
],
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
# Field hints for common error categories
|
|
105
|
+
FIELD_HINTS = {
|
|
106
|
+
ErrorCategory.AUTH_FAILED: "user or password",
|
|
107
|
+
ErrorCategory.NETWORK_UNREACHABLE: "host or port",
|
|
108
|
+
ErrorCategory.DATABASE_NOT_FOUND: "database",
|
|
109
|
+
ErrorCategory.SCHEMA_NOT_FOUND: "schema",
|
|
110
|
+
ErrorCategory.SSL_ERROR: "SSL certificate fields",
|
|
111
|
+
ErrorCategory.INVALID_CONFIG: "account or connection details",
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def normalize_error(database_type: str, error: Exception) -> NormalizedError:
|
|
116
|
+
"""
|
|
117
|
+
Convert database-specific error to normalized, user-friendly format.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
database_type: The database type (e.g., 'postgresql', 'snowflake')
|
|
121
|
+
error: The original exception
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
NormalizedError with category, message, and actionable next steps
|
|
125
|
+
"""
|
|
126
|
+
error_str = str(error).lower()
|
|
127
|
+
original_error = str(error)
|
|
128
|
+
|
|
129
|
+
# Get patterns for this database type, fallback to default
|
|
130
|
+
patterns = ERROR_PATTERNS.get(database_type, []) + ERROR_PATTERNS["_default"]
|
|
131
|
+
|
|
132
|
+
for pattern, category, next_steps in patterns:
|
|
133
|
+
if re.search(pattern, error_str, re.IGNORECASE):
|
|
134
|
+
return NormalizedError(
|
|
135
|
+
category=category,
|
|
136
|
+
message=_get_user_message(category),
|
|
137
|
+
next_steps=next_steps,
|
|
138
|
+
original_error=original_error,
|
|
139
|
+
field_hint=FIELD_HINTS.get(category),
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
# Unknown error
|
|
143
|
+
return NormalizedError(
|
|
144
|
+
category=ErrorCategory.UNKNOWN,
|
|
145
|
+
message="An unexpected error occurred while connecting to the database.",
|
|
146
|
+
next_steps=["Check connection details", "Review error message below", "Contact support if issue persists"],
|
|
147
|
+
original_error=original_error,
|
|
148
|
+
field_hint=None,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def _get_user_message(category: ErrorCategory) -> str:
|
|
153
|
+
"""Get user-friendly message for error category."""
|
|
154
|
+
messages = {
|
|
155
|
+
ErrorCategory.AUTH_FAILED: "Authentication failed. Please check your credentials.",
|
|
156
|
+
ErrorCategory.NETWORK_UNREACHABLE: "Unable to reach the database server.",
|
|
157
|
+
ErrorCategory.DATABASE_NOT_FOUND: "The specified database was not found.",
|
|
158
|
+
ErrorCategory.SCHEMA_NOT_FOUND: "The specified schema was not found.",
|
|
159
|
+
ErrorCategory.TABLE_NOT_FOUND: "The specified table was not found.",
|
|
160
|
+
ErrorCategory.PERMISSION_DENIED: "You don't have permission to perform this action.",
|
|
161
|
+
ErrorCategory.SSL_ERROR: "SSL/TLS connection error. Check certificate configuration.",
|
|
162
|
+
ErrorCategory.TIMEOUT: "Connection timed out.",
|
|
163
|
+
ErrorCategory.INVALID_CONFIG: "Invalid connection configuration.",
|
|
164
|
+
ErrorCategory.UNKNOWN: "An unexpected error occurred.",
|
|
165
|
+
}
|
|
166
|
+
return messages.get(category, messages[ErrorCategory.UNKNOWN])
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def to_api_response(normalized: NormalizedError) -> dict:
|
|
170
|
+
"""Convert NormalizedError to API response format."""
|
|
171
|
+
return {
|
|
172
|
+
"success": False,
|
|
173
|
+
"error": {
|
|
174
|
+
"category": normalized.category.value,
|
|
175
|
+
"message": normalized.message,
|
|
176
|
+
"next_steps": normalized.next_steps,
|
|
177
|
+
"field_hint": normalized.field_hint,
|
|
178
|
+
"details": normalized.original_error,
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pymnemon
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Unified db connector system with normalized error handling across multiple databases.
|
|
5
|
+
Author-email: Causum <support@causum.com>
|
|
6
|
+
Maintainer-email: Causum <support@causum.com>
|
|
7
|
+
License: MIT License
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2026 The pymnemon contributors
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
|
|
29
|
+
Project-URL: Repository, https://gitlab.com/causum/mnemon
|
|
30
|
+
Requires-Python: >=3.9
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Requires-Dist: SQLAlchemy==2.0.45
|
|
34
|
+
Requires-Dist: psycopg2-binary
|
|
35
|
+
Requires-Dist: sqlalchemy-bigquery
|
|
36
|
+
Requires-Dist: google-cloud-bigquery
|
|
37
|
+
Requires-Dist: redshift-connector
|
|
38
|
+
Requires-Dist: clickhouse-driver
|
|
39
|
+
Requires-Dist: clickhouse-sqlalchemy>=0.3
|
|
40
|
+
Requires-Dist: duckdb
|
|
41
|
+
Requires-Dist: PyMySQL
|
|
42
|
+
Requires-Dist: pyodbc
|
|
43
|
+
Requires-Dist: databricks-sql-connector>=3.0
|
|
44
|
+
Requires-Dist: trino
|
|
45
|
+
Requires-Dist: PyHive
|
|
46
|
+
Requires-Dist: vertica-python
|
|
47
|
+
Requires-Dist: oracledb
|
|
48
|
+
Requires-Dist: teradatasql
|
|
49
|
+
Requires-Dist: ibm-db
|
|
50
|
+
Requires-Dist: ibm-db-sa
|
|
51
|
+
Requires-Dist: snowflake-sqlalchemy
|
|
52
|
+
Requires-Dist: google-cloud-bigquery-storage
|
|
53
|
+
Requires-Dist: PyAthena[SQLAlchemy]
|
|
54
|
+
Dynamic: license-file
|
|
55
|
+
|
|
56
|
+
# pymnemon
|
|
57
|
+
|
|
58
|
+
Unified SQLAlchemy connector with normalized error handling across multiple databases.
|
|
59
|
+
|
|
60
|
+
Note: The PyPI package name is `pymnemon`, but the import name is `mnemon`.
|
|
61
|
+
|
|
62
|
+
## Install
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install pymnemon
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Quickstart
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from mnemon import SchemaDBConnection
|
|
72
|
+
|
|
73
|
+
config = {
|
|
74
|
+
"database_type": "postgresql",
|
|
75
|
+
"auth_method": "password",
|
|
76
|
+
"connection": {
|
|
77
|
+
"user": "dbuser",
|
|
78
|
+
"password": "dbpass",
|
|
79
|
+
"host": "localhost",
|
|
80
|
+
"port": 5432,
|
|
81
|
+
"database": "analytics",
|
|
82
|
+
# optional
|
|
83
|
+
# "sslmode": "require",
|
|
84
|
+
},
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
with SchemaDBConnection(config) as db:
|
|
88
|
+
ok, engine, error = db.safe_connect()
|
|
89
|
+
if not ok:
|
|
90
|
+
print(error)
|
|
91
|
+
else:
|
|
92
|
+
rows = db.execute_query("SELECT 1 AS ok")
|
|
93
|
+
print(rows)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Configuration
|
|
97
|
+
|
|
98
|
+
`SchemaDBConnection` expects a config dict with this shape:
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
{
|
|
102
|
+
"database_type": "<supported database>",
|
|
103
|
+
"auth_method": "<supported auth method>",
|
|
104
|
+
"connection": { ... database-specific fields ... }
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Supported databases and auth methods:
|
|
109
|
+
|
|
110
|
+
- postgresql: password, scram, ssl_verify, ssl_cert
|
|
111
|
+
- mysql: password, ssl_verify, ssl_cert
|
|
112
|
+
- mariadb: password, ssl_verify, ssl_cert
|
|
113
|
+
- clickhouse: password, ssl_verify, ssl_cert
|
|
114
|
+
- sqlserver: password
|
|
115
|
+
- trino: none, password, jwt, certificate
|
|
116
|
+
- sparksql: none, password, ldap
|
|
117
|
+
- vertica: password, ldap, ssl_verify
|
|
118
|
+
- oracle: password, wallet
|
|
119
|
+
- teradata: password, ldap
|
|
120
|
+
- db2: password, ldap
|
|
121
|
+
- snowflake: password, key_pair
|
|
122
|
+
- bigquery: service_account
|
|
123
|
+
- redshift: password, iam_role
|
|
124
|
+
- duckdb: local_file, motherduck
|
|
125
|
+
- databricks: token, oauth_m2m
|
|
126
|
+
- athena: iam_credentials
|
|
127
|
+
|
|
128
|
+
### Example configs
|
|
129
|
+
|
|
130
|
+
PostgreSQL (password):
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
{
|
|
134
|
+
"database_type": "postgresql",
|
|
135
|
+
"auth_method": "password",
|
|
136
|
+
"connection": {
|
|
137
|
+
"user": "dbuser",
|
|
138
|
+
"password": "dbpass",
|
|
139
|
+
"host": "localhost",
|
|
140
|
+
"port": 5432,
|
|
141
|
+
"database": "analytics"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Snowflake (key pair):
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
{
|
|
150
|
+
"database_type": "snowflake",
|
|
151
|
+
"auth_method": "key_pair",
|
|
152
|
+
"connection": {
|
|
153
|
+
"account": "xy12345.us-east-1",
|
|
154
|
+
"user": "DBUSER",
|
|
155
|
+
"warehouse": "COMPUTE_WH",
|
|
156
|
+
"database": "ANALYTICS",
|
|
157
|
+
"schema": "PUBLIC",
|
|
158
|
+
"private_key": {"content": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"},
|
|
159
|
+
"private_key_passphrase": "optional"
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
BigQuery (service account):
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
{
|
|
168
|
+
"database_type": "bigquery",
|
|
169
|
+
"auth_method": "service_account",
|
|
170
|
+
"connection": {
|
|
171
|
+
"project": "my-gcp-project",
|
|
172
|
+
"dataset": "analytics",
|
|
173
|
+
"location": "US",
|
|
174
|
+
"credentials_json": {"content": "{... service account json ...}"}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Databricks (PAT):
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
{
|
|
183
|
+
"database_type": "databricks",
|
|
184
|
+
"auth_method": "token",
|
|
185
|
+
"connection": {
|
|
186
|
+
"host": "adb-1234567890.12.azuredatabricks.net",
|
|
187
|
+
"http_path": "/sql/1.0/warehouses/abcd1234",
|
|
188
|
+
"access_token": "dapi..."
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Error handling
|
|
194
|
+
|
|
195
|
+
`safe_connect()` returns `(success, engine, error)` where `error` is a normalized JSON payload with:
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"success": false,
|
|
200
|
+
"error": {
|
|
201
|
+
"category": "auth_failed",
|
|
202
|
+
"message": "Authentication failed. Please check your credentials.",
|
|
203
|
+
"next_steps": ["Verify username and password"],
|
|
204
|
+
"field_hint": "user or password",
|
|
205
|
+
"details": "... original error ..."
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Notes on dependencies
|
|
211
|
+
|
|
212
|
+
Some drivers require system dependencies or extra setup:
|
|
213
|
+
|
|
214
|
+
- `pyodbc` for SQL Server requires an ODBC driver (e.g., ODBC Driver 18).
|
|
215
|
+
- `oracledb` may require Oracle client configuration depending on mode.
|
|
216
|
+
- `PyAthena[SQLAlchemy]` is used for Athena SQLAlchemy dialect support.
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
mnemon/__init__.py,sha256=cqCaWE6LJSQwJ_UFGe_eDMNxv5SKB8wfwBvKeFcjb_k,154
|
|
2
|
+
mnemon/db_connect.py,sha256=9AwOXhtURcl6aSyInIFQu7D9GlE1ks7mlhOUpqMjMXA,26264
|
|
3
|
+
mnemon/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
mnemon/utils/databricks_engine.py,sha256=tAmZxSkihn_YY3itAAlvqfJD7QMctbYfufYpE-xjSYw,5332
|
|
5
|
+
mnemon/utils/dialect_queries.py,sha256=BCAC83UX7bnnUNc-NimiiLCbx98c4Wbakh39p1FKJxo,13740
|
|
6
|
+
mnemon/utils/error_handling.py,sha256=QbsZ3S7pnjF5vMwmz2TAg3Zlrg4HwKT9HzwMDUa4Z_0,9375
|
|
7
|
+
pymnemon-0.1.1.dist-info/licenses/LICENSE,sha256=15QLuwn7sTjGUIFYvN4UOhGRgd-goVM6L5BV3a-dioI,1082
|
|
8
|
+
pymnemon-0.1.1.dist-info/METADATA,sha256=8JQK0WehCgBXihJq4R1hzXlJGLzsJ-UM2kP2AZR3dHo,5881
|
|
9
|
+
pymnemon-0.1.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
10
|
+
pymnemon-0.1.1.dist-info/top_level.txt,sha256=gdVWuvUbAYZHDK1-Uav9qGngx7utfne-k5ixROarUHQ,7
|
|
11
|
+
pymnemon-0.1.1.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 The pymnemon contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
mnemon
|