awslabs.postgres-mcp-server 1.0.3__tar.gz → 1.0.4__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.
- {awslabs_postgres_mcp_server-1.0.3 → awslabs_postgres_mcp_server-1.0.4}/PKG-INFO +73 -1
- {awslabs_postgres_mcp_server-1.0.3 → awslabs_postgres_mcp_server-1.0.4}/README.md +71 -0
- {awslabs_postgres_mcp_server-1.0.3 → awslabs_postgres_mcp_server-1.0.4}/awslabs/postgres_mcp_server/__init__.py +1 -1
- awslabs_postgres_mcp_server-1.0.4/awslabs/postgres_mcp_server/connection/__init__.py +18 -0
- awslabs_postgres_mcp_server-1.0.4/awslabs/postgres_mcp_server/connection/abstract_db_connection.py +68 -0
- awslabs_postgres_mcp_server-1.0.4/awslabs/postgres_mcp_server/connection/db_connection_singleton.py +117 -0
- awslabs_postgres_mcp_server-1.0.4/awslabs/postgres_mcp_server/connection/psycopg_pool_connection.py +287 -0
- awslabs_postgres_mcp_server-1.0.4/awslabs/postgres_mcp_server/connection/rds_api_connection.py +157 -0
- awslabs_postgres_mcp_server-1.0.4/awslabs/postgres_mcp_server/server.py +323 -0
- {awslabs_postgres_mcp_server-1.0.3 → awslabs_postgres_mcp_server-1.0.4}/pyproject.toml +2 -1
- awslabs_postgres_mcp_server-1.0.4/tests/conftest.py +597 -0
- awslabs_postgres_mcp_server-1.0.4/tests/test_psycopg_connector.py +402 -0
- {awslabs_postgres_mcp_server-1.0.3 → awslabs_postgres_mcp_server-1.0.4}/tests/test_server.py +179 -4
- awslabs_postgres_mcp_server-1.0.4/tests/test_singleton.py +116 -0
- {awslabs_postgres_mcp_server-1.0.3 → awslabs_postgres_mcp_server-1.0.4}/uv.lock +488 -447
- awslabs_postgres_mcp_server-1.0.3/awslabs/postgres_mcp_server/server.py +0 -429
- awslabs_postgres_mcp_server-1.0.3/tests/conftest.py +0 -217
- {awslabs_postgres_mcp_server-1.0.3 → awslabs_postgres_mcp_server-1.0.4}/.gitignore +0 -0
- {awslabs_postgres_mcp_server-1.0.3 → awslabs_postgres_mcp_server-1.0.4}/.python-version +0 -0
- {awslabs_postgres_mcp_server-1.0.3 → awslabs_postgres_mcp_server-1.0.4}/CHANGELOG.md +0 -0
- {awslabs_postgres_mcp_server-1.0.3 → awslabs_postgres_mcp_server-1.0.4}/Dockerfile +0 -0
- {awslabs_postgres_mcp_server-1.0.3 → awslabs_postgres_mcp_server-1.0.4}/LICENSE +0 -0
- {awslabs_postgres_mcp_server-1.0.3 → awslabs_postgres_mcp_server-1.0.4}/NOTICE +0 -0
- {awslabs_postgres_mcp_server-1.0.3 → awslabs_postgres_mcp_server-1.0.4}/awslabs/__init__.py +0 -0
- {awslabs_postgres_mcp_server-1.0.3 → awslabs_postgres_mcp_server-1.0.4}/awslabs/postgres_mcp_server/mutable_sql_detector.py +0 -0
- {awslabs_postgres_mcp_server-1.0.3 → awslabs_postgres_mcp_server-1.0.4}/docker-healthcheck.sh +0 -0
- {awslabs_postgres_mcp_server-1.0.3 → awslabs_postgres_mcp_server-1.0.4}/uv-requirements.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: awslabs.postgres-mcp-server
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4
|
|
4
4
|
Summary: An AWS Labs Model Context Protocol (MCP) server for postgres
|
|
5
5
|
Project-URL: homepage, https://awslabs.github.io/mcp/
|
|
6
6
|
Project-URL: docs, https://awslabs.github.io/mcp/servers/postgres-mcp-server/
|
|
@@ -25,6 +25,7 @@ Requires-Dist: boto3>=1.38.5
|
|
|
25
25
|
Requires-Dist: botocore>=1.38.5
|
|
26
26
|
Requires-Dist: loguru>=0.7.0
|
|
27
27
|
Requires-Dist: mcp[cli]>=1.11.0
|
|
28
|
+
Requires-Dist: psycopg[pool]>=3.1.12
|
|
28
29
|
Requires-Dist: pydantic>=2.10.6
|
|
29
30
|
Description-Content-Type: text/markdown
|
|
30
31
|
|
|
@@ -58,6 +59,8 @@ An AWS Labs Model Context Protocol (MCP) server for Aurora Postgres
|
|
|
58
59
|
|
|
59
60
|
Configure the MCP server in your MCP client configuration (e.g., for Amazon Q Developer CLI, edit `~/.aws/amazonq/mcp.json`):
|
|
60
61
|
|
|
62
|
+
### Option 1: Using RDS Data API Connection (for Aurora Postgres)
|
|
63
|
+
|
|
61
64
|
```json
|
|
62
65
|
{
|
|
63
66
|
"mcpServers": {
|
|
@@ -83,6 +86,35 @@ Configure the MCP server in your MCP client configuration (e.g., for Amazon Q De
|
|
|
83
86
|
}
|
|
84
87
|
```
|
|
85
88
|
|
|
89
|
+
### Option 2: Using Direct PostgreSQL(psycopg) Connection (for Aurora Postgres and RDS Postgres)
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"mcpServers": {
|
|
94
|
+
"awslabs.postgres-mcp-server": {
|
|
95
|
+
"command": "uvx",
|
|
96
|
+
"args": [
|
|
97
|
+
"awslabs.postgres-mcp-server@latest",
|
|
98
|
+
"--hostname", "[your data]",
|
|
99
|
+
"--secret_arn", "[your data]",
|
|
100
|
+
"--database", "[your data]",
|
|
101
|
+
"--region", "[your data]",
|
|
102
|
+
"--readonly", "True"
|
|
103
|
+
],
|
|
104
|
+
"env": {
|
|
105
|
+
"AWS_PROFILE": "your-aws-profile",
|
|
106
|
+
"AWS_REGION": "us-east-1",
|
|
107
|
+
"FASTMCP_LOG_LEVEL": "ERROR"
|
|
108
|
+
},
|
|
109
|
+
"disabled": false,
|
|
110
|
+
"autoApprove": []
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Note: The `--port` parameter is optional and defaults to 5432 (the standard PostgreSQL port). You only need to specify it if your PostgreSQL instance uses a non-standard port.
|
|
117
|
+
|
|
86
118
|
### Build and install docker image locally on the same host of your LLM client
|
|
87
119
|
|
|
88
120
|
1. 'git clone https://github.com/awslabs/mcp.git'
|
|
@@ -91,6 +123,8 @@ Configure the MCP server in your MCP client configuration (e.g., for Amazon Q De
|
|
|
91
123
|
|
|
92
124
|
### Add or update your LLM client's config with following:
|
|
93
125
|
|
|
126
|
+
#### Option 1: Using RDS Data API Connection (for Aurora Postgres)
|
|
127
|
+
|
|
94
128
|
```json
|
|
95
129
|
{
|
|
96
130
|
"mcpServers": {
|
|
@@ -115,8 +149,46 @@ Configure the MCP server in your MCP client configuration (e.g., for Amazon Q De
|
|
|
115
149
|
}
|
|
116
150
|
```
|
|
117
151
|
|
|
152
|
+
#### Option 2: Using Direct PostgreSQL (psycopg) Connection (for Aurora Postgres and RDS Postgres)
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
{
|
|
156
|
+
"mcpServers": {
|
|
157
|
+
"awslabs.postgres-mcp-server": {
|
|
158
|
+
"command": "docker",
|
|
159
|
+
"args": [
|
|
160
|
+
"run",
|
|
161
|
+
"-i",
|
|
162
|
+
"--rm",
|
|
163
|
+
"-e", "AWS_ACCESS_KEY_ID=[your data]",
|
|
164
|
+
"-e", "AWS_SECRET_ACCESS_KEY=[your data]",
|
|
165
|
+
"-e", "AWS_REGION=[your data]",
|
|
166
|
+
"awslabs/postgres-mcp-server:latest",
|
|
167
|
+
"--hostname", "[your data]",
|
|
168
|
+
"--secret_arn", "[your data]",
|
|
169
|
+
"--database", "[your data]",
|
|
170
|
+
"--region", "[your data]",
|
|
171
|
+
"--readonly", "True"
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Note: The `--port` parameter is optional and defaults to 5432 (the standard PostgreSQL port). You only need to specify it if your PostgreSQL instance uses a non-standard port.
|
|
179
|
+
|
|
118
180
|
NOTE: By default, only read-only queries are allowed and it is controlled by --readonly parameter above. Set it to False if you also want to allow writable DML or DDL.
|
|
119
181
|
|
|
182
|
+
## Connection Methods
|
|
183
|
+
|
|
184
|
+
This MCP server supports two connection methods:
|
|
185
|
+
|
|
186
|
+
1. **RDS Data API Connection** (using `--resource_arn`): Uses the AWS RDS Data API to connect to Aurora PostgreSQL. This method requires that your Aurora cluster has the Data API enabled.
|
|
187
|
+
|
|
188
|
+
2. **Direct PostgreSQL Connection** (using `--hostname`): Uses psycopg to connect directly to any PostgreSQL database, including Aurora PostgreSQL, RDS PostgreSQL, or self-hosted PostgreSQL instances. This method provides better performance for frequent queries but requires direct network access to the database.
|
|
189
|
+
|
|
190
|
+
Choose the connection method that best fits your environment and requirements.
|
|
191
|
+
|
|
120
192
|
### AWS Authentication
|
|
121
193
|
|
|
122
194
|
The MCP server uses the AWS profile specified in the `AWS_PROFILE` environment variable. If not provided, it defaults to the "default" profile in your AWS configuration file.
|
|
@@ -28,6 +28,8 @@ An AWS Labs Model Context Protocol (MCP) server for Aurora Postgres
|
|
|
28
28
|
|
|
29
29
|
Configure the MCP server in your MCP client configuration (e.g., for Amazon Q Developer CLI, edit `~/.aws/amazonq/mcp.json`):
|
|
30
30
|
|
|
31
|
+
### Option 1: Using RDS Data API Connection (for Aurora Postgres)
|
|
32
|
+
|
|
31
33
|
```json
|
|
32
34
|
{
|
|
33
35
|
"mcpServers": {
|
|
@@ -53,6 +55,35 @@ Configure the MCP server in your MCP client configuration (e.g., for Amazon Q De
|
|
|
53
55
|
}
|
|
54
56
|
```
|
|
55
57
|
|
|
58
|
+
### Option 2: Using Direct PostgreSQL(psycopg) Connection (for Aurora Postgres and RDS Postgres)
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"mcpServers": {
|
|
63
|
+
"awslabs.postgres-mcp-server": {
|
|
64
|
+
"command": "uvx",
|
|
65
|
+
"args": [
|
|
66
|
+
"awslabs.postgres-mcp-server@latest",
|
|
67
|
+
"--hostname", "[your data]",
|
|
68
|
+
"--secret_arn", "[your data]",
|
|
69
|
+
"--database", "[your data]",
|
|
70
|
+
"--region", "[your data]",
|
|
71
|
+
"--readonly", "True"
|
|
72
|
+
],
|
|
73
|
+
"env": {
|
|
74
|
+
"AWS_PROFILE": "your-aws-profile",
|
|
75
|
+
"AWS_REGION": "us-east-1",
|
|
76
|
+
"FASTMCP_LOG_LEVEL": "ERROR"
|
|
77
|
+
},
|
|
78
|
+
"disabled": false,
|
|
79
|
+
"autoApprove": []
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Note: The `--port` parameter is optional and defaults to 5432 (the standard PostgreSQL port). You only need to specify it if your PostgreSQL instance uses a non-standard port.
|
|
86
|
+
|
|
56
87
|
### Build and install docker image locally on the same host of your LLM client
|
|
57
88
|
|
|
58
89
|
1. 'git clone https://github.com/awslabs/mcp.git'
|
|
@@ -61,6 +92,8 @@ Configure the MCP server in your MCP client configuration (e.g., for Amazon Q De
|
|
|
61
92
|
|
|
62
93
|
### Add or update your LLM client's config with following:
|
|
63
94
|
|
|
95
|
+
#### Option 1: Using RDS Data API Connection (for Aurora Postgres)
|
|
96
|
+
|
|
64
97
|
```json
|
|
65
98
|
{
|
|
66
99
|
"mcpServers": {
|
|
@@ -85,8 +118,46 @@ Configure the MCP server in your MCP client configuration (e.g., for Amazon Q De
|
|
|
85
118
|
}
|
|
86
119
|
```
|
|
87
120
|
|
|
121
|
+
#### Option 2: Using Direct PostgreSQL (psycopg) Connection (for Aurora Postgres and RDS Postgres)
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
{
|
|
125
|
+
"mcpServers": {
|
|
126
|
+
"awslabs.postgres-mcp-server": {
|
|
127
|
+
"command": "docker",
|
|
128
|
+
"args": [
|
|
129
|
+
"run",
|
|
130
|
+
"-i",
|
|
131
|
+
"--rm",
|
|
132
|
+
"-e", "AWS_ACCESS_KEY_ID=[your data]",
|
|
133
|
+
"-e", "AWS_SECRET_ACCESS_KEY=[your data]",
|
|
134
|
+
"-e", "AWS_REGION=[your data]",
|
|
135
|
+
"awslabs/postgres-mcp-server:latest",
|
|
136
|
+
"--hostname", "[your data]",
|
|
137
|
+
"--secret_arn", "[your data]",
|
|
138
|
+
"--database", "[your data]",
|
|
139
|
+
"--region", "[your data]",
|
|
140
|
+
"--readonly", "True"
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Note: The `--port` parameter is optional and defaults to 5432 (the standard PostgreSQL port). You only need to specify it if your PostgreSQL instance uses a non-standard port.
|
|
148
|
+
|
|
88
149
|
NOTE: By default, only read-only queries are allowed and it is controlled by --readonly parameter above. Set it to False if you also want to allow writable DML or DDL.
|
|
89
150
|
|
|
151
|
+
## Connection Methods
|
|
152
|
+
|
|
153
|
+
This MCP server supports two connection methods:
|
|
154
|
+
|
|
155
|
+
1. **RDS Data API Connection** (using `--resource_arn`): Uses the AWS RDS Data API to connect to Aurora PostgreSQL. This method requires that your Aurora cluster has the Data API enabled.
|
|
156
|
+
|
|
157
|
+
2. **Direct PostgreSQL Connection** (using `--hostname`): Uses psycopg to connect directly to any PostgreSQL database, including Aurora PostgreSQL, RDS PostgreSQL, or self-hosted PostgreSQL instances. This method provides better performance for frequent queries but requires direct network access to the database.
|
|
158
|
+
|
|
159
|
+
Choose the connection method that best fits your environment and requirements.
|
|
160
|
+
|
|
90
161
|
### AWS Authentication
|
|
91
162
|
|
|
92
163
|
The MCP server uses the AWS profile specified in the `AWS_PROFILE` environment variable. If not provided, it defaults to the "default" profile in your AWS configuration file.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""aws.postgres-mcp-server.connection"""
|
|
16
|
+
|
|
17
|
+
from awslabs.postgres_mcp_server.connection.db_connection_singleton import DBConnectionSingleton
|
|
18
|
+
from awslabs.postgres_mcp_server.connection.abstract_db_connection import AbstractDBConnection
|
awslabs_postgres_mcp_server-1.0.4/awslabs/postgres_mcp_server/connection/abstract_db_connection.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""Abstract database connection interface for postgres MCP Server."""
|
|
16
|
+
|
|
17
|
+
from abc import ABC, abstractmethod
|
|
18
|
+
from typing import Any, Dict, List, Optional
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class AbstractDBConnection(ABC):
|
|
22
|
+
"""Abstract base class for database connections."""
|
|
23
|
+
|
|
24
|
+
def __init__(self, readonly: bool):
|
|
25
|
+
"""Initialize the database connection.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
readonly: Whether the connection should be read-only
|
|
29
|
+
"""
|
|
30
|
+
self._readonly = readonly
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def readonly_query(self) -> bool:
|
|
34
|
+
"""Get whether this connection is read-only.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
bool: True if the connection is read-only, False otherwise
|
|
38
|
+
"""
|
|
39
|
+
return self._readonly
|
|
40
|
+
|
|
41
|
+
@abstractmethod
|
|
42
|
+
async def execute_query(
|
|
43
|
+
self, sql: str, parameters: Optional[List[Dict[str, Any]]] = None
|
|
44
|
+
) -> Dict[str, Any]:
|
|
45
|
+
"""Execute a SQL query.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
sql: The SQL query to execute
|
|
49
|
+
parameters: Optional parameters for the query
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Dict containing query results with column metadata and records
|
|
53
|
+
"""
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
@abstractmethod
|
|
57
|
+
async def close(self) -> None:
|
|
58
|
+
"""Close the database connection."""
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
@abstractmethod
|
|
62
|
+
async def check_connection_health(self) -> bool:
|
|
63
|
+
"""Check if the database connection is healthy.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
bool: True if the connection is healthy, False otherwise
|
|
67
|
+
"""
|
|
68
|
+
pass
|
awslabs_postgres_mcp_server-1.0.4/awslabs/postgres_mcp_server/connection/db_connection_singleton.py
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""Database connection singleton for postgres MCP Server."""
|
|
16
|
+
|
|
17
|
+
import asyncio
|
|
18
|
+
from awslabs.postgres_mcp_server.connection.rds_api_connection import RDSDataAPIConnection
|
|
19
|
+
from loguru import logger
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class DBConnectionSingleton:
|
|
23
|
+
"""Manages a single RDS Data API connection instance across the application."""
|
|
24
|
+
|
|
25
|
+
_instance = None
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
resource_arn: str,
|
|
30
|
+
secret_arn: str,
|
|
31
|
+
database: str,
|
|
32
|
+
region: str,
|
|
33
|
+
readonly: bool = True,
|
|
34
|
+
is_test: bool = False,
|
|
35
|
+
):
|
|
36
|
+
"""Initialize a new DB connection singleton for RDS Data API.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
resource_arn: The ARN of the RDS cluster
|
|
40
|
+
secret_arn: The ARN of the secret containing credentials
|
|
41
|
+
database: The name of the database to connect to
|
|
42
|
+
region: The AWS region where the RDS instance is located
|
|
43
|
+
readonly: Whether the connection should be read-only (default: True)
|
|
44
|
+
is_test: Whether this is a test connection (default: False)
|
|
45
|
+
"""
|
|
46
|
+
if not all([resource_arn, secret_arn, database, region]):
|
|
47
|
+
raise ValueError(
|
|
48
|
+
'Missing required connection parameters for RDS Data API. '
|
|
49
|
+
'Please provide resource_arn, secret_arn, database, and region.'
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
self._db_connection = RDSDataAPIConnection(
|
|
53
|
+
cluster_arn=resource_arn,
|
|
54
|
+
secret_arn=secret_arn,
|
|
55
|
+
database=database,
|
|
56
|
+
region=region,
|
|
57
|
+
readonly=readonly,
|
|
58
|
+
is_test=is_test,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
@classmethod
|
|
62
|
+
def initialize(
|
|
63
|
+
cls,
|
|
64
|
+
resource_arn: str,
|
|
65
|
+
secret_arn: str,
|
|
66
|
+
database: str,
|
|
67
|
+
region: str,
|
|
68
|
+
readonly: bool = True,
|
|
69
|
+
is_test: bool = False,
|
|
70
|
+
):
|
|
71
|
+
"""Initialize the singleton instance if it doesn't exist.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
resource_arn: The ARN of the RDS cluster
|
|
75
|
+
secret_arn: The ARN of the secret containing credentials
|
|
76
|
+
database: The name of the database to connect to
|
|
77
|
+
region: The AWS region where the RDS instance is located
|
|
78
|
+
readonly: Whether the connection should be read-only (default: True)
|
|
79
|
+
is_test: Whether this is a test connection (default: False)
|
|
80
|
+
"""
|
|
81
|
+
if cls._instance is None:
|
|
82
|
+
cls._instance = cls(
|
|
83
|
+
resource_arn=resource_arn,
|
|
84
|
+
secret_arn=secret_arn,
|
|
85
|
+
database=database,
|
|
86
|
+
region=region,
|
|
87
|
+
readonly=readonly,
|
|
88
|
+
is_test=is_test,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
@classmethod
|
|
92
|
+
def get(cls):
|
|
93
|
+
"""Get the singleton instance."""
|
|
94
|
+
if cls._instance is None:
|
|
95
|
+
raise RuntimeError('DBConnectionSingleton is not initialized.')
|
|
96
|
+
return cls._instance
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def db_connection(self):
|
|
100
|
+
"""Get the database connection."""
|
|
101
|
+
return self._db_connection
|
|
102
|
+
|
|
103
|
+
@classmethod
|
|
104
|
+
def cleanup(cls):
|
|
105
|
+
"""Clean up resources when shutting down."""
|
|
106
|
+
if cls._instance and cls._instance._db_connection:
|
|
107
|
+
# Handle calling async close method from sync context
|
|
108
|
+
try:
|
|
109
|
+
loop = asyncio.get_event_loop()
|
|
110
|
+
if loop.is_running():
|
|
111
|
+
# If we're in an async context, create a task
|
|
112
|
+
asyncio.create_task(cls._instance._db_connection.close())
|
|
113
|
+
else:
|
|
114
|
+
# If we're in a sync context, run the coroutine to completion
|
|
115
|
+
loop.run_until_complete(cls._instance._db_connection.close())
|
|
116
|
+
except Exception as e:
|
|
117
|
+
logger.error(f'Error during connection cleanup: {str(e)}')
|