Skip to content

Commit db6aab0

Browse files
authored
Merge pull request #196 from mindsdb/database-api
Include Params in Database GETs
2 parents f629eb5 + 0f684e5 commit db6aab0

File tree

2 files changed

+63
-34
lines changed

2 files changed

+63
-34
lines changed

mindsdb_sdk/databases.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import List, Union
1+
from typing import Dict, List, Union
22

33
from mindsdb_sql_parser.ast.mindsdb import CreateDatabase
44
from mindsdb_sql_parser.ast import DropDatabase, Identifier
@@ -15,7 +15,7 @@ class Database:
1515
Allows to work with database (datasource): to use tables and make raw queries
1616
1717
To run native query
18-
At this moment query is just saved in Qeury object and not executed
18+
At this moment query is just saved in Query object and not executed
1919
2020
>>> query = database.query('select * from table1') # returns Query
2121
@@ -27,11 +27,12 @@ class Database:
2727
2828
"""
2929

30-
def __init__(self, server, name, engine=None):
30+
def __init__(self, server, name: str, engine: str = None, params: Dict = None):
3131
self.server = server
3232
self.name = name
3333
self.engine = engine
3434
self.api = server.api
35+
self.params = params
3536

3637
self.tables = Tables(self, self.api)
3738

@@ -49,6 +50,7 @@ def query(self, sql: str) -> Query:
4950
Make raw query to integration
5051
5152
:param sql: sql of the query
53+
:param database: name of database to query (uses current database by default)
5254
:return: Query object
5355
"""
5456
return Query(self.api, sql, database=self.name)
@@ -65,7 +67,7 @@ class Databases(CollectionBase):
6567
# create
6668
6769
>>> db = databases.create('example_db',
68-
... type='postgres',
70+
... engine='postgres',
6971
... connection_args={'host': ''})
7072
7173
# drop database
@@ -81,11 +83,16 @@ class Databases(CollectionBase):
8183
def __init__(self, api):
8284
self.api = api
8385

84-
def _list_databases(self):
86+
def _list_databases(self) -> Dict[str, Database]:
8587
data = self.api.sql_query(
86-
"select NAME, ENGINE from information_schema.databases where TYPE='data'"
88+
"select NAME, ENGINE, CONNECTION_DATA from information_schema.databases where TYPE='data'"
8789
)
88-
return dict(zip(data.NAME, data.ENGINE))
90+
name_to_db = {}
91+
for _, row in data.iterrows():
92+
name_to_db[row["NAME"]] = Database(
93+
self, row["NAME"], engine=row["ENGINE"], params=row["CONNECTION_DATA"]
94+
)
95+
return name_to_db
8996

9097
def list(self) -> List[Database]:
9198
"""
@@ -94,9 +101,11 @@ def list(self) -> List[Database]:
94101
:return: list of Database objects
95102
"""
96103
databases = self._list_databases()
97-
return [Database(self, name, engine=engine) for name, engine in databases.items()]
104+
return list(databases.values())
98105

99-
def create(self, name: str, engine: Union[str, Handler], connection_args: dict) -> Database:
106+
def create(
107+
self, name: str, engine: Union[str, Handler], connection_args: Dict
108+
) -> Database:
100109
"""
101110
Create new integration and return it
102111
@@ -114,7 +123,7 @@ def create(self, name: str, engine: Union[str, Handler], connection_args: dict)
114123
parameters=connection_args,
115124
)
116125
self.api.sql_query(ast_query.to_string())
117-
return Database(self, name, engine=engine)
126+
return Database(self, name, engine=engine, params=connection_args)
118127

119128
def drop(self, name: str):
120129
"""
@@ -135,4 +144,4 @@ def get(self, name: str) -> Database:
135144
databases = self._list_databases()
136145
if name not in databases:
137146
raise AttributeError("Database doesn't exist")
138-
return Database(self, name, engine=databases[name])
147+
return databases[name]

tests/test_sdk.py

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,25 @@ def test_flow(self, mock_post, mock_put, mock_get):
237237
assert call_args[0][0] == 'https://cloud.mindsdb.com/api/status'
238238

239239
# --------- databases -------------
240-
response_mock(mock_post, pd.DataFrame([{'NAME': 'db1','ENGINE': 'postgres'}]))
240+
response_mock(
241+
mock_post,
242+
pd.DataFrame(
243+
[
244+
{
245+
"NAME": "db1",
246+
"ENGINE": "postgres",
247+
"CONNECTION_DATA": {"host": "zoop"},
248+
}
249+
]
250+
),
251+
)
241252

242253
databases = server.list_databases()
243254

244-
check_sql_call(mock_post, "select NAME, ENGINE from information_schema.databases where TYPE='data'")
255+
check_sql_call(
256+
mock_post,
257+
"select NAME, ENGINE, CONNECTION_DATA from information_schema.databases where TYPE='data'",
258+
)
245259

246260
database = databases[0]
247261
str(database)
@@ -283,7 +297,7 @@ def test_flow(self, mock_post, mock_put, mock_get):
283297
check_sql_call(mock_post, 'DROP DATABASE `proj1-1`')
284298

285299
# test upload file
286-
response_mock(mock_post, pd.DataFrame([{'NAME': 'files', 'ENGINE': 'file'}]))
300+
response_mock(mock_post, pd.DataFrame([{'NAME': 'files', 'ENGINE': 'file', 'CONNECTION_DATA': {'host': 'woop'}}]))
287301
database = server.get_database('files')
288302
# create file
289303
df = pd.DataFrame([{'s': '1'}, {'s': 'a'}])
@@ -465,7 +479,6 @@ def check_project_models(self, project, database, mock_post):
465479
}
466480
)
467481

468-
469482
@patch('requests.Session.post')
470483
def check_project_models_versions(self, project, database, mock_post):
471484
# ----------- model version --------------
@@ -495,7 +508,6 @@ def check_project_models_versions(self, project, database, mock_post):
495508
project.drop_model_version('m1', 1)
496509
check_sql_call(mock_post, f"DROP PREDICTOR m1.`1`")
497510

498-
499511
@patch('requests.Session.post')
500512
def check_database(self, database, mock_post):
501513

@@ -545,7 +557,6 @@ def check_database(self, database, mock_post):
545557
database.drop_table('t3')
546558
check_sql_call(mock_post, f'drop table {database.name}.t3')
547559

548-
549560
@patch('requests.Session.post')
550561
def check_project_jobs(self, project, mock_post):
551562

@@ -608,11 +619,11 @@ def test_flow(self, mock_post, mock_put):
608619
assert call_args[1]['json']['email'] == '[email protected]'
609620

610621
# --------- databases -------------
611-
response_mock(mock_post, pd.DataFrame([{'NAME': 'db1', 'ENGINE': 'postgres'}]))
622+
response_mock(mock_post, pd.DataFrame([{'NAME': 'db1', 'ENGINE': 'postgres', 'CONNECTION_DATA': {}}]))
612623

613624
databases = con.databases.list()
614625

615-
check_sql_call(mock_post, "select NAME, ENGINE from information_schema.databases where TYPE='data'")
626+
check_sql_call(mock_post, "select NAME, ENGINE, CONNECTION_DATA from information_schema.databases where TYPE='data'")
616627

617628
database = databases[0]
618629
assert database.name == 'db1'
@@ -659,7 +670,7 @@ def test_flow(self, mock_post, mock_put):
659670
check_sql_call(mock_post, 'DROP DATABASE `proj1-1`')
660671

661672
# test upload file
662-
response_mock(mock_post, pd.DataFrame([{'NAME': 'files', 'ENGINE': 'file'}]))
673+
response_mock(mock_post, pd.DataFrame([{'NAME': 'files', 'ENGINE': 'file', 'CONNECTION_DATA': {}}]))
663674
database = con.databases.files
664675
# create file
665676
df = pd.DataFrame([{'s': '1'}, {'s': 'a'}])
@@ -1415,7 +1426,6 @@ def test_create(self, mock_get, mock_post):
14151426

14161427
assert new_agent == expected_agent
14171428

1418-
14191429
@patch('requests.Session.get')
14201430
@patch('requests.Session.put')
14211431
# Mock creating new skills.
@@ -1480,7 +1490,6 @@ def test_update(self, mock_get, mock_put, _):
14801490

14811491
assert updated_agent == expected_agent
14821492

1483-
14841493
@patch('requests.Session.post')
14851494
def test_completion(self, mock_post):
14861495
response_mock(mock_post, {
@@ -1693,18 +1702,29 @@ def test_add_database(self, mock_post, mock_put, mock_get):
16931702
'provider': 'mindsdb'
16941703
},
16951704
])
1696-
responses_mock(mock_post, [
1697-
# DB get (POST /sql).
1698-
pd.DataFrame([
1699-
{'NAME': 'existing_db', 'ENGINE': 'postgres'}
1700-
]),
1701-
# DB tables get (POST /sql).
1702-
pd.DataFrame([
1703-
{'name': 'existing_table'}
1704-
]),
1705-
# Skill creation.
1706-
{'name': 'new_skill', 'type': 'sql', 'params': {'database': 'existing_db', 'tables': ['existing_table']}}
1707-
])
1705+
responses_mock(
1706+
mock_post,
1707+
[
1708+
# DB get (POST /sql).
1709+
pd.DataFrame(
1710+
[
1711+
{
1712+
"NAME": "existing_db",
1713+
"ENGINE": "postgres",
1714+
"CONNECTION_DATA": {"host": "boop"},
1715+
}
1716+
]
1717+
),
1718+
# DB tables get (POST /sql).
1719+
pd.DataFrame([{"name": "existing_table"}]),
1720+
# Skill creation.
1721+
{
1722+
"name": "new_skill",
1723+
"type": "sql",
1724+
"params": {"database": "existing_db", "tables": ["existing_table"]},
1725+
},
1726+
],
1727+
)
17081728
responses_mock(mock_put, [
17091729
# Agent update with new skill.
17101730
{

0 commit comments

Comments
 (0)