stitchdb 1.0.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.
- stitchdb-1.0.0/PKG-INFO +55 -0
- stitchdb-1.0.0/README.md +23 -0
- stitchdb-1.0.0/setup.cfg +4 -0
- stitchdb-1.0.0/setup.py +30 -0
- stitchdb-1.0.0/stitchdb.egg-info/PKG-INFO +55 -0
- stitchdb-1.0.0/stitchdb.egg-info/SOURCES.txt +15 -0
- stitchdb-1.0.0/stitchdb.egg-info/dependency_links.txt +1 -0
- stitchdb-1.0.0/stitchdb.egg-info/requires.txt +2 -0
- stitchdb-1.0.0/stitchdb.egg-info/top_level.txt +1 -0
- stitchdb-1.0.0/stitchdb_django/__init__.py +1 -0
- stitchdb-1.0.0/stitchdb_django/base.py +156 -0
- stitchdb-1.0.0/stitchdb_django/client.py +27 -0
- stitchdb-1.0.0/stitchdb_django/creation.py +9 -0
- stitchdb-1.0.0/stitchdb_django/features.py +8 -0
- stitchdb-1.0.0/stitchdb_django/introspection.py +5 -0
- stitchdb-1.0.0/stitchdb_django/operations.py +5 -0
- stitchdb-1.0.0/stitchdb_django/schema.py +5 -0
stitchdb-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: stitchdb
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: StitchDB database backend for Django
|
|
5
|
+
Home-page: https://github.com/stitchdb/django
|
|
6
|
+
Author: StitchDB
|
|
7
|
+
Author-email: support@stitchdb.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Classifier: Framework :: Django
|
|
10
|
+
Classifier: Framework :: Django :: 3.2
|
|
11
|
+
Classifier: Framework :: Django :: 4.0
|
|
12
|
+
Classifier: Framework :: Django :: 4.1
|
|
13
|
+
Classifier: Framework :: Django :: 4.2
|
|
14
|
+
Classifier: Framework :: Django :: 5.0
|
|
15
|
+
Classifier: Framework :: Django :: 5.1
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Requires-Python: >=3.7
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
Requires-Dist: django>=3.2
|
|
21
|
+
Requires-Dist: requests>=2.25.0
|
|
22
|
+
Dynamic: author
|
|
23
|
+
Dynamic: author-email
|
|
24
|
+
Dynamic: classifier
|
|
25
|
+
Dynamic: description
|
|
26
|
+
Dynamic: description-content-type
|
|
27
|
+
Dynamic: home-page
|
|
28
|
+
Dynamic: license
|
|
29
|
+
Dynamic: requires-dist
|
|
30
|
+
Dynamic: requires-python
|
|
31
|
+
Dynamic: summary
|
|
32
|
+
|
|
33
|
+
# StitchDB for Django
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install stitchdb
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Configure
|
|
42
|
+
|
|
43
|
+
In `settings.py`:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
DATABASES = {
|
|
47
|
+
'default': {
|
|
48
|
+
'ENGINE': 'stitchdb_django',
|
|
49
|
+
'URL': os.environ.get('STITCHDB_URL', 'https://db.stitchdb.com'),
|
|
50
|
+
'API_KEY': os.environ.get('STITCHDB_API_KEY', ''),
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
No other setup needed. Run `python manage.py migrate` and use Django ORM as usual.
|
stitchdb-1.0.0/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# StitchDB for Django
|
|
2
|
+
|
|
3
|
+
## Install
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install stitchdb
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Configure
|
|
10
|
+
|
|
11
|
+
In `settings.py`:
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
DATABASES = {
|
|
15
|
+
'default': {
|
|
16
|
+
'ENGINE': 'stitchdb_django',
|
|
17
|
+
'URL': os.environ.get('STITCHDB_URL', 'https://db.stitchdb.com'),
|
|
18
|
+
'API_KEY': os.environ.get('STITCHDB_API_KEY', ''),
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
No other setup needed. Run `python manage.py migrate` and use Django ORM as usual.
|
stitchdb-1.0.0/setup.cfg
ADDED
stitchdb-1.0.0/setup.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="stitchdb",
|
|
5
|
+
version="1.0.0",
|
|
6
|
+
description="StitchDB database backend for Django",
|
|
7
|
+
long_description=open("README.md").read(),
|
|
8
|
+
long_description_content_type="text/markdown",
|
|
9
|
+
author="StitchDB",
|
|
10
|
+
author_email="support@stitchdb.com",
|
|
11
|
+
url="https://github.com/stitchdb/django",
|
|
12
|
+
packages=find_packages(),
|
|
13
|
+
install_requires=[
|
|
14
|
+
"django>=3.2",
|
|
15
|
+
"requests>=2.25.0",
|
|
16
|
+
],
|
|
17
|
+
python_requires=">=3.7",
|
|
18
|
+
license="MIT",
|
|
19
|
+
classifiers=[
|
|
20
|
+
"Framework :: Django",
|
|
21
|
+
"Framework :: Django :: 3.2",
|
|
22
|
+
"Framework :: Django :: 4.0",
|
|
23
|
+
"Framework :: Django :: 4.1",
|
|
24
|
+
"Framework :: Django :: 4.2",
|
|
25
|
+
"Framework :: Django :: 5.0",
|
|
26
|
+
"Framework :: Django :: 5.1",
|
|
27
|
+
"Programming Language :: Python :: 3",
|
|
28
|
+
"License :: OSI Approved :: MIT License",
|
|
29
|
+
],
|
|
30
|
+
)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: stitchdb
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: StitchDB database backend for Django
|
|
5
|
+
Home-page: https://github.com/stitchdb/django
|
|
6
|
+
Author: StitchDB
|
|
7
|
+
Author-email: support@stitchdb.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Classifier: Framework :: Django
|
|
10
|
+
Classifier: Framework :: Django :: 3.2
|
|
11
|
+
Classifier: Framework :: Django :: 4.0
|
|
12
|
+
Classifier: Framework :: Django :: 4.1
|
|
13
|
+
Classifier: Framework :: Django :: 4.2
|
|
14
|
+
Classifier: Framework :: Django :: 5.0
|
|
15
|
+
Classifier: Framework :: Django :: 5.1
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Requires-Python: >=3.7
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
Requires-Dist: django>=3.2
|
|
21
|
+
Requires-Dist: requests>=2.25.0
|
|
22
|
+
Dynamic: author
|
|
23
|
+
Dynamic: author-email
|
|
24
|
+
Dynamic: classifier
|
|
25
|
+
Dynamic: description
|
|
26
|
+
Dynamic: description-content-type
|
|
27
|
+
Dynamic: home-page
|
|
28
|
+
Dynamic: license
|
|
29
|
+
Dynamic: requires-dist
|
|
30
|
+
Dynamic: requires-python
|
|
31
|
+
Dynamic: summary
|
|
32
|
+
|
|
33
|
+
# StitchDB for Django
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install stitchdb
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Configure
|
|
42
|
+
|
|
43
|
+
In `settings.py`:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
DATABASES = {
|
|
47
|
+
'default': {
|
|
48
|
+
'ENGINE': 'stitchdb_django',
|
|
49
|
+
'URL': os.environ.get('STITCHDB_URL', 'https://db.stitchdb.com'),
|
|
50
|
+
'API_KEY': os.environ.get('STITCHDB_API_KEY', ''),
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
No other setup needed. Run `python manage.py migrate` and use Django ORM as usual.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
setup.py
|
|
3
|
+
stitchdb.egg-info/PKG-INFO
|
|
4
|
+
stitchdb.egg-info/SOURCES.txt
|
|
5
|
+
stitchdb.egg-info/dependency_links.txt
|
|
6
|
+
stitchdb.egg-info/requires.txt
|
|
7
|
+
stitchdb.egg-info/top_level.txt
|
|
8
|
+
stitchdb_django/__init__.py
|
|
9
|
+
stitchdb_django/base.py
|
|
10
|
+
stitchdb_django/client.py
|
|
11
|
+
stitchdb_django/creation.py
|
|
12
|
+
stitchdb_django/features.py
|
|
13
|
+
stitchdb_django/introspection.py
|
|
14
|
+
stitchdb_django/operations.py
|
|
15
|
+
stitchdb_django/schema.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
stitchdb_django
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""StitchDB database backend for Django."""
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"""
|
|
2
|
+
StitchDB database backend for Django.
|
|
3
|
+
Wraps the StitchDB HTTP API behind Django's database backend interface.
|
|
4
|
+
Uses SQLite-compatible SQL since StitchDB uses SQLite under the hood.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from django.db.backends.sqlite3.base import DatabaseWrapper as SQLiteDatabaseWrapper
|
|
8
|
+
from django.db.backends.sqlite3.base import Database
|
|
9
|
+
from .client import StitchDBClient
|
|
10
|
+
from .creation import DatabaseCreation
|
|
11
|
+
from .features import DatabaseFeatures
|
|
12
|
+
from .introspection import DatabaseIntrospection
|
|
13
|
+
from .operations import DatabaseOperations
|
|
14
|
+
from .schema import DatabaseSchemaEditor
|
|
15
|
+
|
|
16
|
+
import sqlite3
|
|
17
|
+
import json
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class StitchDBCursorWrapper:
|
|
21
|
+
"""A cursor that sends queries to StitchDB's HTTP API."""
|
|
22
|
+
|
|
23
|
+
def __init__(self, client):
|
|
24
|
+
self.client = client
|
|
25
|
+
self.description = None
|
|
26
|
+
self._results = []
|
|
27
|
+
self._rowcount = -1
|
|
28
|
+
self.lastrowid = None
|
|
29
|
+
self.arraysize = 1
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def rowcount(self):
|
|
33
|
+
return self._rowcount
|
|
34
|
+
|
|
35
|
+
def execute(self, sql, params=None):
|
|
36
|
+
sql = str(sql).strip()
|
|
37
|
+
if not sql:
|
|
38
|
+
return
|
|
39
|
+
|
|
40
|
+
# Convert Django's %s placeholders to ? for SQLite
|
|
41
|
+
if params:
|
|
42
|
+
sql = sql.replace("%s", "?")
|
|
43
|
+
params = list(params)
|
|
44
|
+
else:
|
|
45
|
+
params = None
|
|
46
|
+
|
|
47
|
+
try:
|
|
48
|
+
result = self.client.query(sql, params)
|
|
49
|
+
results = result.get("results", [])
|
|
50
|
+
meta = result.get("meta", {})
|
|
51
|
+
|
|
52
|
+
self.lastrowid = meta.get("last_row_id")
|
|
53
|
+
self._rowcount = meta.get("rows_written", len(results))
|
|
54
|
+
|
|
55
|
+
if results and len(results) > 0:
|
|
56
|
+
columns = list(results[0].keys())
|
|
57
|
+
self.description = [
|
|
58
|
+
(col, None, None, None, None, None, None) for col in columns
|
|
59
|
+
]
|
|
60
|
+
self._results = [tuple(row.get(col) for col in columns) for row in results]
|
|
61
|
+
else:
|
|
62
|
+
self.description = None
|
|
63
|
+
self._results = []
|
|
64
|
+
except Exception as e:
|
|
65
|
+
raise Exception(str(e))
|
|
66
|
+
|
|
67
|
+
def executemany(self, sql, param_list):
|
|
68
|
+
for params in param_list:
|
|
69
|
+
self.execute(sql, params)
|
|
70
|
+
|
|
71
|
+
def fetchone(self):
|
|
72
|
+
if self._results:
|
|
73
|
+
return self._results.pop(0)
|
|
74
|
+
return None
|
|
75
|
+
|
|
76
|
+
def fetchmany(self, size=None):
|
|
77
|
+
if size is None:
|
|
78
|
+
size = self.arraysize
|
|
79
|
+
results = self._results[:size]
|
|
80
|
+
self._results = self._results[size:]
|
|
81
|
+
return results
|
|
82
|
+
|
|
83
|
+
def fetchall(self):
|
|
84
|
+
results = self._results
|
|
85
|
+
self._results = []
|
|
86
|
+
return results
|
|
87
|
+
|
|
88
|
+
def close(self):
|
|
89
|
+
pass
|
|
90
|
+
|
|
91
|
+
def __iter__(self):
|
|
92
|
+
return iter(self._results)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class DatabaseWrapper(SQLiteDatabaseWrapper):
|
|
96
|
+
vendor = "stitchdb"
|
|
97
|
+
display_name = "StitchDB"
|
|
98
|
+
|
|
99
|
+
# Use SQLite data types
|
|
100
|
+
data_types = SQLiteDatabaseWrapper.data_types
|
|
101
|
+
|
|
102
|
+
SchemaEditorClass = DatabaseSchemaEditor
|
|
103
|
+
|
|
104
|
+
def __init__(self, *args, **kwargs):
|
|
105
|
+
super().__init__(*args, **kwargs)
|
|
106
|
+
self.features = DatabaseFeatures(self)
|
|
107
|
+
self.ops = DatabaseOperations(self)
|
|
108
|
+
self.creation = DatabaseCreation(self)
|
|
109
|
+
self.introspection = DatabaseIntrospection(self)
|
|
110
|
+
self._stitchdb_client = None
|
|
111
|
+
|
|
112
|
+
def get_stitchdb_client(self):
|
|
113
|
+
if self._stitchdb_client is None:
|
|
114
|
+
url = self.settings_dict.get("URL", "https://db.stitchdb.com")
|
|
115
|
+
api_key = self.settings_dict.get("API_KEY", "")
|
|
116
|
+
self._stitchdb_client = StitchDBClient(url, api_key)
|
|
117
|
+
return self._stitchdb_client
|
|
118
|
+
|
|
119
|
+
def get_connection_params(self):
|
|
120
|
+
return {"database": ":memory:"}
|
|
121
|
+
|
|
122
|
+
def get_new_connection(self, conn_params):
|
|
123
|
+
# We need a real SQLite connection for Django's internals
|
|
124
|
+
# (schema introspection, etc.) but all actual queries go through HTTP
|
|
125
|
+
conn = Database.connect(":memory:")
|
|
126
|
+
return conn
|
|
127
|
+
|
|
128
|
+
def create_cursor(self, name=None):
|
|
129
|
+
return StitchDBCursorWrapper(self.get_stitchdb_client())
|
|
130
|
+
|
|
131
|
+
def _cursor(self):
|
|
132
|
+
return self.create_cursor()
|
|
133
|
+
|
|
134
|
+
def is_usable(self):
|
|
135
|
+
return True
|
|
136
|
+
|
|
137
|
+
def _set_autocommit(self, autocommit):
|
|
138
|
+
pass
|
|
139
|
+
|
|
140
|
+
def _start_transaction_under_autocommit(self):
|
|
141
|
+
pass
|
|
142
|
+
|
|
143
|
+
def _savepoint(self, sid):
|
|
144
|
+
pass
|
|
145
|
+
|
|
146
|
+
def _savepoint_rollback(self, sid):
|
|
147
|
+
pass
|
|
148
|
+
|
|
149
|
+
def _savepoint_commit(self, sid):
|
|
150
|
+
pass
|
|
151
|
+
|
|
152
|
+
def _commit(self):
|
|
153
|
+
pass
|
|
154
|
+
|
|
155
|
+
def _rollback(self):
|
|
156
|
+
pass
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class StitchDBClient:
|
|
5
|
+
def __init__(self, url, api_key):
|
|
6
|
+
self.url = url.rstrip("/")
|
|
7
|
+
self.api_key = api_key
|
|
8
|
+
self.session = requests.Session()
|
|
9
|
+
self.session.headers.update(
|
|
10
|
+
{
|
|
11
|
+
"Authorization": f"Bearer {self.api_key}",
|
|
12
|
+
"Content-Type": "application/json",
|
|
13
|
+
}
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
def query(self, sql, params=None):
|
|
17
|
+
body = {"sql": sql}
|
|
18
|
+
if params:
|
|
19
|
+
body["params"] = list(params)
|
|
20
|
+
resp = self.session.post(f"{self.url}/v1/query", json=body)
|
|
21
|
+
data = resp.json()
|
|
22
|
+
if "error" in data:
|
|
23
|
+
raise Exception(f"StitchDB: {data['error']}")
|
|
24
|
+
return data
|
|
25
|
+
|
|
26
|
+
def execute(self, sql, params=None):
|
|
27
|
+
return self.query(sql, params)
|