sqloader 0.2.6__tar.gz → 0.2.8__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.
Files changed (30) hide show
  1. {sqloader-0.2.6/sqloader.egg-info → sqloader-0.2.8}/PKG-INFO +1 -1
  2. {sqloader-0.2.6 → sqloader-0.2.8}/pyproject.toml +1 -1
  3. {sqloader-0.2.6 → sqloader-0.2.8}/setup.py +1 -1
  4. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader/mysql_async.py +3 -0
  5. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader/postgresql.py +12 -1
  6. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader/postgresql_async.py +3 -0
  7. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader/sqlite3.py +250 -235
  8. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader/sqlite3_async.py +3 -0
  9. {sqloader-0.2.6 → sqloader-0.2.8/sqloader.egg-info}/PKG-INFO +1 -1
  10. {sqloader-0.2.6 → sqloader-0.2.8}/LICENSE +0 -0
  11. {sqloader-0.2.6 → sqloader-0.2.8}/README.md +0 -0
  12. {sqloader-0.2.6 → sqloader-0.2.8}/setup.cfg +0 -0
  13. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader/__init__.py +0 -0
  14. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader/__main__.py +0 -0
  15. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader/_async_prototype.py +0 -0
  16. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader/_prototype.py +0 -0
  17. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader/init.py +0 -0
  18. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader/migrator.py +0 -0
  19. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader/mysql.py +0 -0
  20. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader/sqloader.py +0 -0
  21. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader.egg-info/SOURCES.txt +0 -0
  22. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader.egg-info/dependency_links.txt +0 -0
  23. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader.egg-info/requires.txt +0 -0
  24. {sqloader-0.2.6 → sqloader-0.2.8}/sqloader.egg-info/top_level.txt +0 -0
  25. {sqloader-0.2.6 → sqloader-0.2.8}/tests/test_fetch_aliases.py +0 -0
  26. {sqloader-0.2.6 → sqloader-0.2.8}/tests/test_migrator.py +0 -0
  27. {sqloader-0.2.6 → sqloader-0.2.8}/tests/test_mysql.py +0 -0
  28. {sqloader-0.2.6 → sqloader-0.2.8}/tests/test_postgresql.py +0 -0
  29. {sqloader-0.2.6 → sqloader-0.2.8}/tests/test_sqlite.py +0 -0
  30. {sqloader-0.2.6 → sqloader-0.2.8}/tests/test_sqloader.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqloader
3
- Version: 0.2.6
3
+ Version: 0.2.8
4
4
  Summary: A simple and extensible SQL migration and loader utility for Python.
5
5
  Home-page: https://github.com/horrible-gh/py_sqloader.git
6
6
  Author: horrible-gh
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "sqloader"
7
- version = "0.2.6"
7
+ version = "0.2.8"
8
8
  authors = [
9
9
  { name="horrible", email="shinjpn1@gmail.com" },
10
10
  ]
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='sqloader',
5
- version='0.2.6',
5
+ version='0.2.8',
6
6
  description='py_sqloader package',
7
7
  author='horrible-gh',
8
8
  author_email='shinjpn1@gmail.com',
@@ -89,6 +89,9 @@ class AsyncMySqlWrapper(AsyncDatabasePrototype):
89
89
  print(f"Last query: {query}")
90
90
  raise
91
91
 
92
+ async def execute_query(self, query, params=None, commit=True):
93
+ return await self.execute(query, params, commit)
94
+
92
95
  async def fetchone(self, query, params=None):
93
96
  return await self.fetch_one(query, params)
94
97
 
@@ -49,6 +49,8 @@ class PostgreSQLWrapper(DatabasePrototype):
49
49
  self.log(query)
50
50
  if params is not None:
51
51
  self.log(params)
52
+ if params is not None and not isinstance(params, (tuple, list, dict)):
53
+ params = (params,)
52
54
  cursor.execute(query, params)
53
55
  if commit:
54
56
  conn.commit()
@@ -66,6 +68,9 @@ class PostgreSQLWrapper(DatabasePrototype):
66
68
  self.pool.putconn(conn)
67
69
  query_semaphore.release()
68
70
 
71
+ def execute_query(self, query, params=None, commit=True):
72
+ return self.execute(query, params, commit)
73
+
69
74
  def fetchone(self, query, params=None):
70
75
  return self.fetch_one(query, params)
71
76
 
@@ -80,6 +85,8 @@ class PostgreSQLWrapper(DatabasePrototype):
80
85
  self.log(query)
81
86
  if params is not None:
82
87
  self.log(params)
88
+ if params is not None and not isinstance(params, (tuple, list, dict)):
89
+ params = (params,)
83
90
  cursor.execute(query, params)
84
91
  result = cursor.fetchone()
85
92
  conn.rollback() # Close the implicit transaction before returning to pool
@@ -111,6 +118,8 @@ class PostgreSQLWrapper(DatabasePrototype):
111
118
  self.log(query)
112
119
  if params is not None:
113
120
  self.log(params)
121
+ if params is not None and not isinstance(params, (tuple, list, dict)):
122
+ params = (params,)
114
123
  cursor.execute(query, params)
115
124
  result = cursor.fetchall()
116
125
  conn.rollback() # Close the implicit transaction before returning to pool
@@ -156,6 +165,8 @@ class PostgreSQLTransaction(Transaction):
156
165
  self.cursor = self.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
157
166
 
158
167
  def execute(self, query, params=None):
168
+ if params is not None and not isinstance(params, (tuple, list, dict)):
169
+ params = (params,)
159
170
  return self.cursor.execute(query, params)
160
171
 
161
172
  def fetchall(self):
@@ -188,4 +199,4 @@ class PostgreSQLTransaction(Transaction):
188
199
  self.rollback()
189
200
  else:
190
201
  self.commit()
191
- self.close()
202
+ self.close()
@@ -119,6 +119,9 @@ class AsyncPostgreSQLWrapper(AsyncDatabasePrototype):
119
119
  print(f"Last query: {q}")
120
120
  raise
121
121
 
122
+ async def execute_query(self, query, params=None, commit=True):
123
+ return await self.execute(query, params, commit)
124
+
122
125
  async def fetchone(self, query, params=None):
123
126
  return await self.fetch_one(query, params)
124
127
 
@@ -1,235 +1,250 @@
1
- import sqlite3
2
- import threading
3
- from ._prototype import DatabasePrototype, Transaction, SQLITE
4
- from pathlib import Path
5
-
6
- query_semaphore = None
7
-
8
- db_lock = threading.Lock()
9
-
10
- class SQLiteWrapper(DatabasePrototype):
11
- db_type = SQLITE
12
-
13
- def __init__(self, db_name, memory_mode=False, max_parallel_queries=5):
14
- self.db_name = db_name
15
- self.memory_mode = memory_mode
16
-
17
- if not memory_mode:
18
- # Auto-create parent directories for the database file
19
- Path(self.db_name).parent.mkdir(parents=True, exist_ok=True)
20
-
21
- global query_semaphore
22
- query_semaphore = threading.Semaphore(max_parallel_queries)
23
-
24
- if self.memory_mode:
25
- # In-memory mode: single persistent connection + Lock (serialized access)
26
- self.conn = sqlite3.connect(":memory:", check_same_thread=False)
27
- self.conn.row_factory = sqlite3.Row
28
- self.cursor = self.conn.cursor()
29
- # To restore from a file, use:
30
- # backup_conn = sqlite3.connect(db_name)
31
- # backup_conn.backup(self.conn)
32
- # backup_conn.close()
33
- else:
34
- # File mode: new connection per query via semaphore; no persistent conn needed
35
- self.conn = None
36
- self.cursor = None
37
-
38
- def _execute_memory(self, query, params=None, commit=True):
39
- """In-memory mode: single connection + Lock (serialized)."""
40
- with db_lock:
41
- try:
42
- if params is None:
43
- self.cursor.execute(query)
44
- else:
45
- self.cursor.execute(query, params)
46
- if commit:
47
- self.conn.commit()
48
- return self.cursor.lastrowid
49
- except sqlite3.DatabaseError as e:
50
- print(f"Error executing query: {e}")
51
- self.conn.rollback()
52
- raise e
53
-
54
- def _execute_file(self, query, params=None, commit=True):
55
- """File mode: semaphore + new connection per query (limited parallelism)."""
56
- query_semaphore.acquire()
57
- try:
58
- conn = sqlite3.connect(self.db_name, check_same_thread=False)
59
- conn.row_factory = sqlite3.Row
60
- cursor = conn.cursor()
61
- try:
62
- if params is None:
63
- cursor.execute(query)
64
- else:
65
- cursor.execute(query, params)
66
- if commit:
67
- conn.commit()
68
- return cursor.lastrowid
69
- except sqlite3.DatabaseError as e:
70
- print(f"Error executing query (file mode): {e}")
71
- conn.rollback()
72
- raise e
73
- finally:
74
- cursor.close()
75
- conn.close()
76
- finally:
77
- query_semaphore.release()
78
-
79
- def execute(self, query, params=None, commit=True):
80
- if self.memory_mode:
81
- return self._execute_memory(query, params, commit)
82
- else:
83
- return self._execute_file(query, params, commit)
84
-
85
- def fetchone(self, query, params=None):
86
- return self.fetch_one(query, params)
87
-
88
- def fetch_one(self, query, params=None):
89
- if self.memory_mode:
90
- with db_lock:
91
- try:
92
- if params is None:
93
- self.cursor.execute(query)
94
- else:
95
- self.cursor.execute(query, params)
96
- return self.cursor.fetchone()
97
- except sqlite3.DatabaseError as e:
98
- print(f"Error fetching data (memory mode, fetch_one): {e}")
99
- raise e
100
- else:
101
- # File mode: open a new connection for the fetch
102
- query_semaphore.acquire()
103
- try:
104
- conn = sqlite3.connect(self.db_name, check_same_thread=False)
105
- conn.row_factory = sqlite3.Row
106
- cursor = conn.cursor()
107
- try:
108
- if params is None:
109
- cursor.execute(query)
110
- else:
111
- cursor.execute(query, params)
112
- return cursor.fetchone()
113
- except sqlite3.DatabaseError as e:
114
- print(f"Error fetching data (file mode, fetch_one): {e}")
115
- raise e
116
- finally:
117
- cursor.close()
118
- conn.close()
119
- finally:
120
- query_semaphore.release()
121
-
122
- def fetchall(self, query, params=None):
123
- return self.fetch_all(query, params)
124
-
125
- def fetch_all(self, query, params=None):
126
- if self.memory_mode:
127
- with db_lock:
128
- try:
129
- if params is None:
130
- self.cursor.execute(query)
131
- else:
132
- self.cursor.execute(query, params)
133
- return self.cursor.fetchall()
134
- except sqlite3.DatabaseError as e:
135
- print(f"Error fetching data (memory mode, fetch_all): {e}")
136
- raise e
137
- else:
138
- query_semaphore.acquire()
139
- try:
140
- conn = sqlite3.connect(self.db_name, check_same_thread=False)
141
- conn.row_factory = sqlite3.Row
142
- cursor = conn.cursor()
143
- try:
144
- if params is None:
145
- cursor.execute(query)
146
- else:
147
- cursor.execute(query, params)
148
- return cursor.fetchall()
149
- except sqlite3.DatabaseError as e:
150
- print(f"Error fetching data (file mode, fetch_all): {e}")
151
- raise e
152
- finally:
153
- cursor.close()
154
- conn.close()
155
- finally:
156
- query_semaphore.release()
157
-
158
- def rollback(self):
159
- if self.memory_mode:
160
- with db_lock:
161
- self.conn.rollback()
162
- else:
163
- # File mode uses per-query connections; no persistent connection to rollback
164
- pass
165
-
166
- def commit(self):
167
- if self.memory_mode:
168
- with db_lock:
169
- self.conn.commit()
170
- else:
171
- # File mode uses per-query connections; commit is handled inside each call
172
- pass
173
-
174
- def close(self):
175
- if self.memory_mode:
176
- with db_lock:
177
- self.cursor.close()
178
- self.conn.close()
179
- else:
180
- # File mode has no persistent connection to close
181
- pass
182
-
183
-
184
- def begin_transaction(self):
185
- """Returns a transaction context manager backed by a dedicated connection."""
186
- return SQLiteTransaction(self)
187
-
188
-
189
- class SQLiteTransaction:
190
- def __init__(self, wrapper: SQLiteWrapper):
191
- self.wrapper = wrapper
192
- self.conn = sqlite3.connect(
193
- wrapper.db_name,
194
- check_same_thread=False
195
- )
196
- self.conn.row_factory = sqlite3.Row
197
- self.cursor = self.conn.cursor()
198
-
199
- def execute(self, query, params=None):
200
- if params is None:
201
- return self.cursor.execute(query)
202
- return self.cursor.execute(query, params)
203
-
204
- def fetchall(self):
205
- return self.cursor.fetchall()
206
-
207
- def fetch_all(self):
208
- return self.fetchall()
209
-
210
- def fetchone(self):
211
- return self.cursor.fetchone()
212
-
213
- def fetch_one(self):
214
- return self.fetchone()
215
-
216
- def commit(self):
217
- self.conn.commit()
218
-
219
- def rollback(self):
220
- self.conn.rollback()
221
-
222
- def close(self):
223
- self.cursor.close()
224
- self.conn.close()
225
-
226
- def __enter__(self):
227
- return self
228
-
229
- def __exit__(self, exc_type, exc_val, traceback):
230
- # Rollback on exception, commit otherwise
231
- if exc_type:
232
- self.rollback()
233
- else:
234
- self.commit()
235
- self.close()
1
+ import sqlite3
2
+ import threading
3
+ from ._prototype import DatabasePrototype, Transaction, SQLITE
4
+ from pathlib import Path
5
+
6
+ query_semaphore = None
7
+
8
+ db_lock = threading.Lock()
9
+
10
+ class SQLiteWrapper(DatabasePrototype):
11
+ db_type = SQLITE
12
+
13
+ def __init__(self, db_name, memory_mode=False, max_parallel_queries=5):
14
+ self.db_name = db_name
15
+ self.memory_mode = memory_mode
16
+
17
+ if not memory_mode:
18
+ # Auto-create parent directories for the database file
19
+ Path(self.db_name).parent.mkdir(parents=True, exist_ok=True)
20
+
21
+ global query_semaphore
22
+ query_semaphore = threading.Semaphore(max_parallel_queries)
23
+
24
+ if self.memory_mode:
25
+ # In-memory mode: single persistent connection + Lock (serialized access)
26
+ self.conn = sqlite3.connect(":memory:", check_same_thread=False)
27
+ self.conn.row_factory = sqlite3.Row
28
+ self.cursor = self.conn.cursor()
29
+ # To restore from a file, use:
30
+ # backup_conn = sqlite3.connect(db_name)
31
+ # backup_conn.backup(self.conn)
32
+ # backup_conn.close()
33
+ else:
34
+ # File mode: new connection per query via semaphore; no persistent conn needed
35
+ self.conn = None
36
+ self.cursor = None
37
+
38
+ def _execute_memory(self, query, params=None, commit=True):
39
+ """In-memory mode: single connection + Lock (serialized)."""
40
+ with db_lock:
41
+ try:
42
+ if params is not None and not isinstance(params, (tuple, list, dict)):
43
+ params = (params,)
44
+ if params is None:
45
+ self.cursor.execute(query)
46
+ else:
47
+ self.cursor.execute(query, params)
48
+ if commit:
49
+ self.conn.commit()
50
+ return self.cursor.lastrowid
51
+ except sqlite3.DatabaseError as e:
52
+ print(f"Error executing query: {e}")
53
+ self.conn.rollback()
54
+ raise e
55
+
56
+ def _execute_file(self, query, params=None, commit=True):
57
+ """File mode: semaphore + new connection per query (limited parallelism)."""
58
+ query_semaphore.acquire()
59
+ try:
60
+ conn = sqlite3.connect(self.db_name, check_same_thread=False)
61
+ conn.row_factory = sqlite3.Row
62
+ cursor = conn.cursor()
63
+ try:
64
+ if params is not None and not isinstance(params, (tuple, list, dict)):
65
+ params = (params,)
66
+ if params is None:
67
+ cursor.execute(query)
68
+ else:
69
+ cursor.execute(query, params)
70
+ if commit:
71
+ conn.commit()
72
+ return cursor.lastrowid
73
+ except sqlite3.DatabaseError as e:
74
+ print(f"Error executing query (file mode): {e}")
75
+ conn.rollback()
76
+ raise e
77
+ finally:
78
+ cursor.close()
79
+ conn.close()
80
+ finally:
81
+ query_semaphore.release()
82
+
83
+ def execute(self, query, params=None, commit=True):
84
+ if self.memory_mode:
85
+ return self._execute_memory(query, params, commit)
86
+ else:
87
+ return self._execute_file(query, params, commit)
88
+
89
+ def execute_query(self, query, params=None, commit=True):
90
+ return self.execute(query, params, commit)
91
+
92
+ def fetchone(self, query, params=None):
93
+ return self.fetch_one(query, params)
94
+
95
+ def fetch_one(self, query, params=None):
96
+ if self.memory_mode:
97
+ with db_lock:
98
+ try:
99
+ if params is not None and not isinstance(params, (tuple, list, dict)):
100
+ params = (params,)
101
+ if params is None:
102
+ self.cursor.execute(query)
103
+ else:
104
+ self.cursor.execute(query, params)
105
+ return self.cursor.fetchone()
106
+ except sqlite3.DatabaseError as e:
107
+ print(f"Error fetching data (memory mode, fetch_one): {e}")
108
+ raise e
109
+ else:
110
+ # File mode: open a new connection for the fetch
111
+ query_semaphore.acquire()
112
+ try:
113
+ conn = sqlite3.connect(self.db_name, check_same_thread=False)
114
+ conn.row_factory = sqlite3.Row
115
+ cursor = conn.cursor()
116
+ try:
117
+ if params is not None and not isinstance(params, (tuple, list, dict)):
118
+ params = (params,)
119
+ if params is None:
120
+ cursor.execute(query)
121
+ else:
122
+ cursor.execute(query, params)
123
+ return cursor.fetchone()
124
+ except sqlite3.DatabaseError as e:
125
+ print(f"Error fetching data (file mode, fetch_one): {e}")
126
+ raise e
127
+ finally:
128
+ cursor.close()
129
+ conn.close()
130
+ finally:
131
+ query_semaphore.release()
132
+
133
+ def fetchall(self, query, params=None):
134
+ return self.fetch_all(query, params)
135
+
136
+ def fetch_all(self, query, params=None):
137
+ if self.memory_mode:
138
+ with db_lock:
139
+ try:
140
+ if params is not None and not isinstance(params, (tuple, list, dict)):
141
+ params = (params,)
142
+ if params is None:
143
+ self.cursor.execute(query)
144
+ else:
145
+ self.cursor.execute(query, params)
146
+ return self.cursor.fetchall()
147
+ except sqlite3.DatabaseError as e:
148
+ print(f"Error fetching data (memory mode, fetch_all): {e}")
149
+ raise e
150
+ else:
151
+ query_semaphore.acquire()
152
+ try:
153
+ conn = sqlite3.connect(self.db_name, check_same_thread=False)
154
+ conn.row_factory = sqlite3.Row
155
+ cursor = conn.cursor()
156
+ try:
157
+ if params is not None and not isinstance(params, (tuple, list, dict)):
158
+ params = (params,)
159
+ if params is None:
160
+ cursor.execute(query)
161
+ else:
162
+ cursor.execute(query, params)
163
+ return cursor.fetchall()
164
+ except sqlite3.DatabaseError as e:
165
+ print(f"Error fetching data (file mode, fetch_all): {e}")
166
+ raise e
167
+ finally:
168
+ cursor.close()
169
+ conn.close()
170
+ finally:
171
+ query_semaphore.release()
172
+
173
+ def rollback(self):
174
+ if self.memory_mode:
175
+ with db_lock:
176
+ self.conn.rollback()
177
+ else:
178
+ # File mode uses per-query connections; no persistent connection to rollback
179
+ pass
180
+
181
+ def commit(self):
182
+ if self.memory_mode:
183
+ with db_lock:
184
+ self.conn.commit()
185
+ else:
186
+ # File mode uses per-query connections; commit is handled inside each call
187
+ pass
188
+
189
+ def close(self):
190
+ if self.memory_mode:
191
+ with db_lock:
192
+ self.cursor.close()
193
+ self.conn.close()
194
+ else:
195
+ # File mode has no persistent connection to close
196
+ pass
197
+
198
+
199
+ def begin_transaction(self):
200
+ """Returns a transaction context manager backed by a dedicated connection."""
201
+ return SQLiteTransaction(self)
202
+
203
+
204
+ class SQLiteTransaction:
205
+ def __init__(self, wrapper: SQLiteWrapper):
206
+ self.wrapper = wrapper
207
+ self.conn = sqlite3.connect(
208
+ wrapper.db_name,
209
+ check_same_thread=False
210
+ )
211
+ self.conn.row_factory = sqlite3.Row
212
+ self.cursor = self.conn.cursor()
213
+
214
+ def execute(self, query, params=None):
215
+ if params is None:
216
+ return self.cursor.execute(query)
217
+ return self.cursor.execute(query, params)
218
+
219
+ def fetchall(self):
220
+ return self.cursor.fetchall()
221
+
222
+ def fetch_all(self):
223
+ return self.fetchall()
224
+
225
+ def fetchone(self):
226
+ return self.cursor.fetchone()
227
+
228
+ def fetch_one(self):
229
+ return self.fetchone()
230
+
231
+ def commit(self):
232
+ self.conn.commit()
233
+
234
+ def rollback(self):
235
+ self.conn.rollback()
236
+
237
+ def close(self):
238
+ self.cursor.close()
239
+ self.conn.close()
240
+
241
+ def __enter__(self):
242
+ return self
243
+
244
+ def __exit__(self, exc_type, exc_val, traceback):
245
+ # Rollback on exception, commit otherwise
246
+ if exc_type:
247
+ self.rollback()
248
+ else:
249
+ self.commit()
250
+ self.close()
@@ -94,6 +94,9 @@ class AsyncSQLiteWrapper(AsyncDatabasePrototype):
94
94
  await self._conn.rollback()
95
95
  raise
96
96
 
97
+ async def execute_query(self, query, params=None, commit=True):
98
+ return await self.execute(query, params, commit)
99
+
97
100
  async def fetchone(self, query, params=None):
98
101
  return await self.fetch_one(query, params)
99
102
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqloader
3
- Version: 0.2.6
3
+ Version: 0.2.8
4
4
  Summary: A simple and extensible SQL migration and loader utility for Python.
5
5
  Home-page: https://github.com/horrible-gh/py_sqloader.git
6
6
  Author: horrible-gh
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes