collections-cache 0.1.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.
@@ -0,0 +1,94 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: collections-cache
|
3
|
+
Version: 0.1.0
|
4
|
+
Summary: Collection Cache is a Python package for managing data collections across multiple SQLite databases. It allows efficient storage, retrieval, and updating of key-value pairs, supporting various data types serialized with pickle. The package uses parallel processing for fast access and manipulation of large collections.
|
5
|
+
License: MIT
|
6
|
+
Author: Luiz-Trindade
|
7
|
+
Author-email: luiz.gabriel.m.trindade@gmail.com
|
8
|
+
Requires-Python: >=3.12,<4.0
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
12
|
+
Description-Content-Type: text/markdown
|
13
|
+
|
14
|
+
# Collection Cache
|
15
|
+
|
16
|
+
`Collection Cache` is a simple and efficient caching solution built using SQLite databases. It allows for storing, updating, and retrieving data using unique keys, supporting complex data types through the use of `pickle`. It is designed to scale across multiple CPU cores by distributing the data across multiple SQLite databases.
|
17
|
+
|
18
|
+
## Features
|
19
|
+
|
20
|
+
- **Multiple SQLite databases**: Distributes data across multiple databases for better scalability.
|
21
|
+
- **Key-value store**: Store data as key-value pairs.
|
22
|
+
- **Supports complex data types**: Data is serialized using `pickle`, so you can store lists, dictionaries, and other complex Python objects.
|
23
|
+
- **Parallel processing**: Uses Python’s `multiprocessing` to handle large collections in parallel across multiple CPU cores.
|
24
|
+
- **Efficient data retrieval**: Retrieves stored data based on the key using an efficient search across the collection.
|
25
|
+
|
26
|
+
## Installation
|
27
|
+
|
28
|
+
To install the `Collection Cache` package, use [Poetry](https://python-poetry.org/) for managing dependencies.
|
29
|
+
|
30
|
+
1. Clone the repository:
|
31
|
+
|
32
|
+
```bash
|
33
|
+
git clone https://github.com/Luiz-Trindade/collections_cache.git
|
34
|
+
cd collection-cache
|
35
|
+
```
|
36
|
+
|
37
|
+
2. Install the package with Poetry:
|
38
|
+
|
39
|
+
```bash
|
40
|
+
poetry install
|
41
|
+
```
|
42
|
+
|
43
|
+
## Usage
|
44
|
+
|
45
|
+
To use the `Collection Cache` package, you can import the main class `Collection_Cache` and interact with your collection.
|
46
|
+
|
47
|
+
### Example:
|
48
|
+
|
49
|
+
```python
|
50
|
+
from collection_cache import Collection_Cache
|
51
|
+
|
52
|
+
# Create a new collection
|
53
|
+
cache = Collection_Cache("STORE")
|
54
|
+
|
55
|
+
# Set a key-value pair
|
56
|
+
cache.set_key("alunos", ["Luiz", "Marcos", "João"])
|
57
|
+
|
58
|
+
# Get the value by key
|
59
|
+
students = cache.get_key("alunos")
|
60
|
+
print(students) # Output: ['Luiz', 'Marcos', 'João']
|
61
|
+
```
|
62
|
+
|
63
|
+
### Methods:
|
64
|
+
|
65
|
+
- **`set_key(key, value)`**: Set a key-value pair in the cache. If the key already exists, it will be updated.
|
66
|
+
- **`get_key(key)`**: Retrieve the value associated with a key.
|
67
|
+
- **`create_collection()`**: Initializes the collection and sets up databases for key-value storage.
|
68
|
+
- **`get_all_keys()`**: Retrieves all keys from the collection.
|
69
|
+
|
70
|
+
## Development
|
71
|
+
|
72
|
+
To contribute or run tests:
|
73
|
+
|
74
|
+
1. Install development dependencies:
|
75
|
+
|
76
|
+
```bash
|
77
|
+
poetry install --dev
|
78
|
+
```
|
79
|
+
|
80
|
+
2. Run tests:
|
81
|
+
|
82
|
+
```bash
|
83
|
+
poetry run pytest
|
84
|
+
```
|
85
|
+
|
86
|
+
## License
|
87
|
+
|
88
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
89
|
+
|
90
|
+
## Acknowledgements
|
91
|
+
|
92
|
+
- This package was created to demonstrate how to work with SQLite, `pickle`, and Python's `multiprocessing` module.
|
93
|
+
|
94
|
+
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# Collection Cache
|
2
|
+
|
3
|
+
`Collection Cache` is a simple and efficient caching solution built using SQLite databases. It allows for storing, updating, and retrieving data using unique keys, supporting complex data types through the use of `pickle`. It is designed to scale across multiple CPU cores by distributing the data across multiple SQLite databases.
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
- **Multiple SQLite databases**: Distributes data across multiple databases for better scalability.
|
8
|
+
- **Key-value store**: Store data as key-value pairs.
|
9
|
+
- **Supports complex data types**: Data is serialized using `pickle`, so you can store lists, dictionaries, and other complex Python objects.
|
10
|
+
- **Parallel processing**: Uses Python’s `multiprocessing` to handle large collections in parallel across multiple CPU cores.
|
11
|
+
- **Efficient data retrieval**: Retrieves stored data based on the key using an efficient search across the collection.
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
To install the `Collection Cache` package, use [Poetry](https://python-poetry.org/) for managing dependencies.
|
16
|
+
|
17
|
+
1. Clone the repository:
|
18
|
+
|
19
|
+
```bash
|
20
|
+
git clone https://github.com/Luiz-Trindade/collections_cache.git
|
21
|
+
cd collection-cache
|
22
|
+
```
|
23
|
+
|
24
|
+
2. Install the package with Poetry:
|
25
|
+
|
26
|
+
```bash
|
27
|
+
poetry install
|
28
|
+
```
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
To use the `Collection Cache` package, you can import the main class `Collection_Cache` and interact with your collection.
|
33
|
+
|
34
|
+
### Example:
|
35
|
+
|
36
|
+
```python
|
37
|
+
from collection_cache import Collection_Cache
|
38
|
+
|
39
|
+
# Create a new collection
|
40
|
+
cache = Collection_Cache("STORE")
|
41
|
+
|
42
|
+
# Set a key-value pair
|
43
|
+
cache.set_key("alunos", ["Luiz", "Marcos", "João"])
|
44
|
+
|
45
|
+
# Get the value by key
|
46
|
+
students = cache.get_key("alunos")
|
47
|
+
print(students) # Output: ['Luiz', 'Marcos', 'João']
|
48
|
+
```
|
49
|
+
|
50
|
+
### Methods:
|
51
|
+
|
52
|
+
- **`set_key(key, value)`**: Set a key-value pair in the cache. If the key already exists, it will be updated.
|
53
|
+
- **`get_key(key)`**: Retrieve the value associated with a key.
|
54
|
+
- **`create_collection()`**: Initializes the collection and sets up databases for key-value storage.
|
55
|
+
- **`get_all_keys()`**: Retrieves all keys from the collection.
|
56
|
+
|
57
|
+
## Development
|
58
|
+
|
59
|
+
To contribute or run tests:
|
60
|
+
|
61
|
+
1. Install development dependencies:
|
62
|
+
|
63
|
+
```bash
|
64
|
+
poetry install --dev
|
65
|
+
```
|
66
|
+
|
67
|
+
2. Run tests:
|
68
|
+
|
69
|
+
```bash
|
70
|
+
poetry run pytest
|
71
|
+
```
|
72
|
+
|
73
|
+
## License
|
74
|
+
|
75
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
76
|
+
|
77
|
+
## Acknowledgements
|
78
|
+
|
79
|
+
- This package was created to demonstrate how to work with SQLite, `pickle`, and Python's `multiprocessing` module.
|
80
|
+
|
File without changes
|
@@ -0,0 +1,106 @@
|
|
1
|
+
import sqlite3
|
2
|
+
from multiprocessing import Pool
|
3
|
+
from os import cpu_count, path, makedirs, scandir
|
4
|
+
from itertools import chain
|
5
|
+
from random import choice
|
6
|
+
#from threading import Thread as task
|
7
|
+
import pickle
|
8
|
+
|
9
|
+
class Collection_Cache:
|
10
|
+
def __init__(self, collection_name):
|
11
|
+
self.collection_name = collection_name
|
12
|
+
self.cpu_cores = cpu_count()
|
13
|
+
self.collection_dir = path.join("./Collections", self.collection_name)
|
14
|
+
self.databases_list = []
|
15
|
+
self.keys_databases = {}
|
16
|
+
|
17
|
+
#print(f"Collection '{self.collection_name}' created!")
|
18
|
+
#print(f"Number of cpu cores: {self.cpu_cores}")
|
19
|
+
self.create_collection()
|
20
|
+
self.get_all_databases()
|
21
|
+
|
22
|
+
def create_collection(self):
|
23
|
+
makedirs(self.collection_dir, exist_ok=True)
|
24
|
+
|
25
|
+
for core in range(self.cpu_cores):
|
26
|
+
db_path = path.join(self.collection_dir, f"database_{core}.db")
|
27
|
+
self.initialize_databases(db_path)
|
28
|
+
|
29
|
+
def initialize_databases(self, db_path):
|
30
|
+
conn = sqlite3.connect(db_path)
|
31
|
+
conn.execute("PRAGMA journal_mode=WAL;")
|
32
|
+
conn.execute("""
|
33
|
+
CREATE TABLE IF NOT EXISTS data(
|
34
|
+
key TEXT,
|
35
|
+
value BLOB
|
36
|
+
);
|
37
|
+
""")
|
38
|
+
conn.close()
|
39
|
+
|
40
|
+
def get_all_databases(self):
|
41
|
+
#print("Obtaining all keys...")
|
42
|
+
with scandir(self.collection_dir) as contents:
|
43
|
+
self.databases_list = [path.join(self.collection_dir, content.name) for content in contents]
|
44
|
+
|
45
|
+
with Pool(self.cpu_cores) as pool:
|
46
|
+
self.keys_databases = dict(chain.from_iterable(pool.map(self.get_all_keys, self.databases_list)))
|
47
|
+
#print(self.keys_databases)
|
48
|
+
|
49
|
+
def get_all_keys(self, database):
|
50
|
+
conn = sqlite3.connect(database)
|
51
|
+
cursor = conn.cursor()
|
52
|
+
cursor.execute("PRAGMA journal_mode=WAL;")
|
53
|
+
cursor.execute("SELECT key FROM data;")
|
54
|
+
result = cursor.fetchall()
|
55
|
+
keys = [(line[0], database) for line in result]
|
56
|
+
conn.close()
|
57
|
+
return keys
|
58
|
+
|
59
|
+
def set_key(self, key, value):
|
60
|
+
if key not in self.keys_databases:
|
61
|
+
database_to_insert = choice(self.databases_list)
|
62
|
+
#print(f"Inserting in {database_to_insert}")
|
63
|
+
conn = sqlite3.connect(database_to_insert)
|
64
|
+
cursor = conn.cursor()
|
65
|
+
cursor.execute("PRAGMA journal_mode=WAL;")
|
66
|
+
cursor.execute("INSERT INTO data(key, value) VALUES (?, ?);", (key, pickle.dumps(value)))
|
67
|
+
conn.commit()
|
68
|
+
conn.close()
|
69
|
+
self.add_to_keys_database(key, database_to_insert)
|
70
|
+
|
71
|
+
else:
|
72
|
+
#print(f"Updating key '{key}' in {self.keys_databases[key]}...")
|
73
|
+
database_to_update = self.keys_databases[key]
|
74
|
+
conn = sqlite3.connect(database_to_update)
|
75
|
+
cursor = conn.cursor()
|
76
|
+
cursor.execute("PRAGMA journal_mode=WAL;")
|
77
|
+
cursor.execute("UPDATE data SET value = ? WHERE key = ?;", (pickle.dumps(value), key))
|
78
|
+
conn.commit()
|
79
|
+
conn.close()
|
80
|
+
#print(f"Key '{key}' updated successfully in {database_to_update}")
|
81
|
+
|
82
|
+
def add_to_keys_database(self, key, database):
|
83
|
+
self.keys_databases[key] = database
|
84
|
+
#print(self.keys_databases)
|
85
|
+
|
86
|
+
def get_key(self, key):
|
87
|
+
try:
|
88
|
+
database_to_search = self.keys_databases[key]
|
89
|
+
#print(database_to_search)
|
90
|
+
|
91
|
+
conn = sqlite3.connect(database_to_search)
|
92
|
+
cursor = conn.cursor()
|
93
|
+
cursor.execute("PRAGMA journal_mode=WAL;")
|
94
|
+
cursor.execute("SELECT value FROM data WHERE key = ?", (key,))
|
95
|
+
result = cursor.fetchall()
|
96
|
+
conn.close()
|
97
|
+
return pickle.loads(result[0][0])
|
98
|
+
|
99
|
+
except Exception as error:
|
100
|
+
return error
|
101
|
+
|
102
|
+
conn = Collection_Cache("STORE")
|
103
|
+
conn.set_key("alunos", ["Luiz", "Marcos", "João"])
|
104
|
+
|
105
|
+
alunos = conn.get_key("alunos")
|
106
|
+
print(alunos)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
[tool.poetry]
|
2
|
+
name = "collections-cache"
|
3
|
+
version = "0.1.0"
|
4
|
+
description = "Collection Cache is a Python package for managing data collections across multiple SQLite databases. It allows efficient storage, retrieval, and updating of key-value pairs, supporting various data types serialized with pickle. The package uses parallel processing for fast access and manipulation of large collections."
|
5
|
+
authors = ["Luiz-Trindade <luiz.gabriel.m.trindade@gmail.com>"]
|
6
|
+
license = "MIT"
|
7
|
+
readme = "README.md"
|
8
|
+
|
9
|
+
[tool.poetry.dependencies]
|
10
|
+
python = "^3.12"
|
11
|
+
|
12
|
+
|
13
|
+
[build-system]
|
14
|
+
requires = ["poetry-core"]
|
15
|
+
build-backend = "poetry.core.masonry.api"
|