backo 0.3.4__tar.gz → 0.3.6__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.
- backo-0.3.6/.github/workflows/test.yml +97 -0
- backo-0.3.4/.github/workflows/test.yml → backo-0.3.6/.github/workflows/test_examples.yml +4 -11
- {backo-0.3.4 → backo-0.3.6}/CHANGELOG.md +28 -0
- {backo-0.3.4 → backo-0.3.6}/PKG-INFO +25 -8
- {backo-0.3.4 → backo-0.3.6}/README.md +23 -6
- {backo-0.3.4 → backo-0.3.6}/backo/__init__.py +3 -1
- {backo-0.3.4 → backo-0.3.6}/backo/backoffice.py +12 -4
- {backo-0.3.4 → backo-0.3.6}/backo/collection.py +136 -52
- {backo-0.3.4 → backo-0.3.6}/backo/db/__init__.py +1 -0
- {backo-0.3.4 → backo-0.3.6}/backo/db/backo_redirect.py +2 -1
- {backo-0.3.4 → backo-0.3.6}/backo/db/generic/db_handler.py +6 -15
- {backo-0.3.4 → backo-0.3.6}/backo/db/generic/filter.py +34 -4
- {backo-0.3.4 → backo-0.3.6}/backo/db/generic/transformer.py +75 -0
- backo-0.3.6/backo/db/generic/transformer_cache.py +101 -0
- {backo-0.3.4 → backo-0.3.6}/backo/db/memory.py +9 -6
- {backo-0.3.4 → backo-0.3.6}/backo/db/mongo.py +101 -29
- {backo-0.3.4 → backo-0.3.6}/backo/db/restfull.py +31 -4
- {backo-0.3.4 → backo-0.3.6}/backo/db/sqlite3/db_handler.py +25 -3
- backo-0.3.6/backo/db/sqlite3/filter.py +225 -0
- {backo-0.3.4 → backo-0.3.6}/backo/db/sqlite3/pragma.py +1 -1
- {backo-0.3.4 → backo-0.3.6}/backo/db/sqlite3/transformers.py +22 -0
- {backo-0.3.4 → backo-0.3.6}/backo/db/valkeydb.py +8 -5
- {backo-0.3.4 → backo-0.3.6}/backo/db/yml.py +4 -2
- {backo-0.3.4 → backo-0.3.6}/backo/db/yml_dir.py +12 -8
- {backo-0.3.4 → backo-0.3.6}/backo/error.py +40 -0
- {backo-0.3.4 → backo-0.3.6}/backo/item.py +16 -5
- {backo-0.3.4 → backo-0.3.6}/backo/log.py +17 -1
- {backo-0.3.4 → backo-0.3.6}/backo/loop_path.py +10 -3
- backo-0.3.4/backo/migration_report.py → backo-0.3.6/backo/migration.py +17 -0
- {backo-0.3.4 → backo-0.3.6}/backo/openapi.py +0 -2
- backo-0.3.6/backo/ref.py +533 -0
- {backo-0.3.4 → backo-0.3.6}/backo/refs_strategies.py +16 -0
- backo-0.3.6/backo/refslist.py +703 -0
- {backo-0.3.4 → backo-0.3.6}/backo/selection.py +24 -5
- backo-0.3.6/backo/sort.py +94 -0
- {backo-0.3.4 → backo-0.3.6}/pyproject.toml +2 -2
- {backo-0.3.4 → backo-0.3.6}/tests/__init__.py +1 -0
- {backo-0.3.4 → backo-0.3.6}/tests/test_db_connector.py +28 -3
- backo-0.3.6/tests/test_db_connector_cache.py +95 -0
- {backo-0.3.4 → backo-0.3.6}/tests/test_log.py +5 -0
- {backo-0.3.4 → backo-0.3.6}/tests/test_migrations.py +11 -8
- backo-0.3.6/tests/test_reference.py +756 -0
- backo-0.3.6/tests/test_rest_api_connector.py +110 -0
- {backo-0.3.4 → backo-0.3.6}/tests/test_routes.py +7 -5
- {backo-0.3.4 → backo-0.3.6}/tests/test_selections.py +13 -2
- {backo-0.3.4 → backo-0.3.6}/uv.lock +5 -5
- backo-0.3.4/.github/workflows/test_examples.yml +0 -35
- backo-0.3.4/backo/db/sqlite3/filter.py +0 -149
- backo-0.3.4/backo/ref.py +0 -527
- backo-0.3.4/backo/refslist.py +0 -634
- backo-0.3.4/tests/test_reference.py +0 -1233
- backo-0.3.4/tests/test_rest_api_connector.py +0 -498
- {backo-0.3.4 → backo-0.3.6}/.coveragerc +0 -0
- {backo-0.3.4 → backo-0.3.6}/.github/workflows/pylint.yml +0 -0
- {backo-0.3.4 → backo-0.3.6}/.github/workflows/release.yml +0 -0
- {backo-0.3.4 → backo-0.3.6}/.gitignore +0 -0
- {backo-0.3.4 → backo-0.3.6}/.pylintrc +0 -0
- {backo-0.3.4 → backo-0.3.6}/.readthedocs.yaml +0 -0
- {backo-0.3.4 → backo-0.3.6}/CONTRIBUTING.md +0 -0
- {backo-0.3.4 → backo-0.3.6}/LICENSE +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/action.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/api_toolbox.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/collection_addon.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/current_user.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/db/generic/interface.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/db/sqlite3/__init__.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/file/blob_file.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/file/file.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/file/file_blob_connector.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/file/file_connector.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/file/file_system_connector.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/initialisation/init_script.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/initialisation/templates/__init__.pytemplate +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/initialisation/templates/backoffice.pytemplate +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/initialisation/templates/collection.pytemplate +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/meta_data_handler.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/patch.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/request_decorators.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/status.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/backo/transaction.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/docs/Makefile +0 -0
- {backo-0.3.4 → backo-0.3.6}/docs/make.bat +0 -0
- {backo-0.3.4 → backo-0.3.6}/docs/requirements.txt +0 -0
- {backo-0.3.4 → backo-0.3.6}/docs/source/DB_management.md +0 -0
- {backo-0.3.4 → backo-0.3.6}/docs/source/api_reference.rst +0 -0
- {backo-0.3.4 → backo-0.3.6}/docs/source/conf.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/docs/source/errors.rst +0 -0
- {backo-0.3.4 → backo-0.3.6}/docs/source/index.rst +0 -0
- {backo-0.3.4 → backo-0.3.6}/docs/source/readme.rst +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/media_library/README.md +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/media_library/__init__.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/media_library/backoffice.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/media_library/collections_set/__init__.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/media_library/collections_set/books.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/media_library/collections_set/users.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/media_library/migration.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/media_library/tests.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/nationality/README.md +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/nationality/__init__.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/nationality/backoffice.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/nationality/collections_set/__init__.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/nationality/collections_set/countries.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/nationality/collections_set/db_country_connector.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/nationality/collections_set/people.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/nationality/tests.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/rest_api_connector/README.md +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/rest_api_connector/__init__.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/rest_api_connector/backoffice.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/rest_api_connector/collections_set/__init__.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/rest_api_connector/collections_set/users.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/rest_api_connector/collections_set/vms.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/rest_api_connector/collections_set/vms_connector.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/rest_api_connector/config.yaml +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/rest_api_connector/constants.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/rest_api_connector/requirements.txt +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/rest_api_connector/rest-api/README.md +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/rest_api_connector/rest-api/collections_set/__init__.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/rest_api_connector/rest-api/collections_set/vms.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/rest_api_connector/rest-api/config.yaml +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/rest_api_connector/rest-api/constants.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/examples/rest_api_connector/rest-api/rest_api.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/requirements.txt +0 -0
- {backo-0.3.4 → backo-0.3.6}/tests/test_action.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/tests/test_api_toolbox.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/tests/test_crud.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/tests/test_current_user.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/tests/test_file.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/tests/test_meta.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/tests/test_mongo.py +0 -0
- {backo-0.3.4 → backo-0.3.6}/tests/test_openapi.py +0 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
name: CodeCov
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
on_main:
|
|
7
|
+
if: github.ref == 'refs/heads/main'
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
strategy:
|
|
10
|
+
matrix:
|
|
11
|
+
python-version:
|
|
12
|
+
- "3.12"
|
|
13
|
+
- "3.13"
|
|
14
|
+
- "3.14"
|
|
15
|
+
services:
|
|
16
|
+
mongodb:
|
|
17
|
+
image: mongo:latest
|
|
18
|
+
env:
|
|
19
|
+
# MONGO_INITDB_ROOT_USERNAME: admin
|
|
20
|
+
# MONGO_INITDB_ROOT_PASSWORD: admin
|
|
21
|
+
MONGO_INITDB_DATABASE: testMongo
|
|
22
|
+
ports:
|
|
23
|
+
- 27017:27017
|
|
24
|
+
valkey:
|
|
25
|
+
image: valkey/valkey:latest
|
|
26
|
+
ports:
|
|
27
|
+
- "6379:6379"
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v3
|
|
30
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
31
|
+
uses: actions/setup-python@v3
|
|
32
|
+
with:
|
|
33
|
+
python-version: ${{ matrix.python-version }}
|
|
34
|
+
|
|
35
|
+
- name: Install uv
|
|
36
|
+
uses: astral-sh/setup-uv@v1
|
|
37
|
+
with:
|
|
38
|
+
version: "latest"
|
|
39
|
+
|
|
40
|
+
- name: Install Python
|
|
41
|
+
run: uv python install
|
|
42
|
+
|
|
43
|
+
- name: Install dependencies
|
|
44
|
+
run: |
|
|
45
|
+
sudo apt-get install libmagic1
|
|
46
|
+
uv sync --all-groups --all-extras
|
|
47
|
+
|
|
48
|
+
- name: run tests and coverage
|
|
49
|
+
run: |
|
|
50
|
+
uv run coverage run -m unittest tests
|
|
51
|
+
uv run coverage report -m
|
|
52
|
+
uv run coverage xml
|
|
53
|
+
on_branches:
|
|
54
|
+
if: github.ref != 'refs/heads/main'
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
strategy:
|
|
57
|
+
matrix:
|
|
58
|
+
python-version:
|
|
59
|
+
- "3.14"
|
|
60
|
+
services:
|
|
61
|
+
mongodb:
|
|
62
|
+
image: mongo:latest
|
|
63
|
+
env:
|
|
64
|
+
# MONGO_INITDB_ROOT_USERNAME: admin
|
|
65
|
+
# MONGO_INITDB_ROOT_PASSWORD: admin
|
|
66
|
+
MONGO_INITDB_DATABASE: testMongo
|
|
67
|
+
ports:
|
|
68
|
+
- 27017:27017
|
|
69
|
+
valkey:
|
|
70
|
+
image: valkey/valkey:latest
|
|
71
|
+
ports:
|
|
72
|
+
- "6379:6379"
|
|
73
|
+
steps:
|
|
74
|
+
- uses: actions/checkout@v3
|
|
75
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
76
|
+
uses: actions/setup-python@v3
|
|
77
|
+
with:
|
|
78
|
+
python-version: ${{ matrix.python-version }}
|
|
79
|
+
|
|
80
|
+
- name: Install uv
|
|
81
|
+
uses: astral-sh/setup-uv@v1
|
|
82
|
+
with:
|
|
83
|
+
version: "latest"
|
|
84
|
+
|
|
85
|
+
- name: Install Python
|
|
86
|
+
run: uv python install
|
|
87
|
+
|
|
88
|
+
- name: Install dependencies
|
|
89
|
+
run: |
|
|
90
|
+
sudo apt-get install libmagic1
|
|
91
|
+
uv sync --all-groups --all-extras
|
|
92
|
+
|
|
93
|
+
- name: run tests and coverage
|
|
94
|
+
run: |
|
|
95
|
+
uv run coverage run -m unittest tests
|
|
96
|
+
uv run coverage report -m
|
|
97
|
+
uv run coverage xml
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
name:
|
|
1
|
+
name: TestExamples
|
|
2
2
|
|
|
3
3
|
on: [push, pull_request]
|
|
4
4
|
|
|
@@ -12,15 +12,9 @@ jobs:
|
|
|
12
12
|
mongodb:
|
|
13
13
|
image: mongo:latest
|
|
14
14
|
env:
|
|
15
|
-
# MONGO_INITDB_ROOT_USERNAME: admin
|
|
16
|
-
# MONGO_INITDB_ROOT_PASSWORD: admin
|
|
17
15
|
MONGO_INITDB_DATABASE: testMongo
|
|
18
16
|
ports:
|
|
19
17
|
- 27017:27017
|
|
20
|
-
valkey:
|
|
21
|
-
image: valkey/valkey:latest
|
|
22
|
-
ports:
|
|
23
|
-
- "6379:6379"
|
|
24
18
|
steps:
|
|
25
19
|
- uses: actions/checkout@v3
|
|
26
20
|
- name: Set up Python ${{ matrix.python-version }}
|
|
@@ -41,8 +35,7 @@ jobs:
|
|
|
41
35
|
sudo apt-get install libmagic1
|
|
42
36
|
uv sync --all-groups --all-extras
|
|
43
37
|
|
|
44
|
-
- name:
|
|
38
|
+
- name: Run media library tests
|
|
39
|
+
working-directory: examples/media_library
|
|
45
40
|
run: |
|
|
46
|
-
uv run
|
|
47
|
-
uv run coverage report -m
|
|
48
|
-
uv run coverage xml
|
|
41
|
+
uv run python -m unittest tests
|
|
@@ -5,6 +5,34 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
7
7
|
|
|
8
|
+
## [0.3.6] 2026-09-17
|
|
9
|
+
|
|
10
|
+
* Feat
|
|
11
|
+
* sorting on selection
|
|
12
|
+
* sorting in Sqlite3DBConnector and DBMongoConnector
|
|
13
|
+
* sorting in routes with _sort= in the query string
|
|
14
|
+
|
|
15
|
+
* Internal :
|
|
16
|
+
* Adding FilterReport for evaluation of SFilters into the DB
|
|
17
|
+
* test refacto for Ref and RefsList
|
|
18
|
+
* refacto Ref and RefsList
|
|
19
|
+
|
|
20
|
+
* Fix
|
|
21
|
+
* import __futures__ error on validation parameters
|
|
22
|
+
* fix bug on selector in Ref and RefsList
|
|
23
|
+
|
|
24
|
+
## [0.3.5] 2026-09-15
|
|
25
|
+
|
|
26
|
+
* fix
|
|
27
|
+
* DBHandler pagination bug fix
|
|
28
|
+
* BREAKING CHANGE : New option migration MigrationStrategy (strategy=)
|
|
29
|
+
* BREAKING CHANGE : Removing option FillStrategy (ofs=) for Ref
|
|
30
|
+
|
|
31
|
+
* Internal :
|
|
32
|
+
* Pagination during migration
|
|
33
|
+
* test refacto for Ref and RefsList
|
|
34
|
+
* refacto Ref and RefsList
|
|
35
|
+
|
|
8
36
|
## [0.3.4] 2026-09-04
|
|
9
37
|
|
|
10
38
|
* fix : total routes bug fix
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: backo
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.6
|
|
4
4
|
Summary: Back office low code
|
|
5
5
|
Project-URL: GitHub, https://github.com/backo-stricto/backo
|
|
6
6
|
Project-URL: Homepage, https://github.com/backo-stricto/backo
|
|
@@ -41,7 +41,7 @@ Requires-Dist: pyyaml
|
|
|
41
41
|
Requires-Dist: questionary
|
|
42
42
|
Requires-Dist: redis>=8.1.0
|
|
43
43
|
Requires-Dist: requests
|
|
44
|
-
Requires-Dist: stricto>=0.2.
|
|
44
|
+
Requires-Dist: stricto>=0.2.6
|
|
45
45
|
Provides-Extra: mongo
|
|
46
46
|
Requires-Dist: pymongo>=4.17.0; extra == 'mongo'
|
|
47
47
|
Description-Content-Type: text/markdown
|
|
@@ -878,6 +878,7 @@ Get a list of objects matching the query string. The query string can be with th
|
|
|
878
878
|
| \_view | string | "client" | selects the view ([stricto views](https://github.com/backo-stricto/stricto?tab=readme-ov-file#views)) |
|
|
879
879
|
| \_page | int | - | sets the desired number of items per page in paginated data presentation |
|
|
880
880
|
| \_skip | int | - | skips the n-first items of the result list in paginated data presentation. |
|
|
881
|
+
| \_sort | string | - | give the list of sorting fields |
|
|
881
882
|
| \_total | whatyouwant | None | Just compute the total of object and return { 'total' : x } without taking pagination in account |
|
|
882
883
|
|
|
883
884
|
|
|
@@ -893,9 +894,9 @@ The request returns a HTTP status `200` with that JSON object:
|
|
|
893
894
|
```
|
|
894
895
|
|
|
895
896
|
##### Example
|
|
896
|
-
Select all users whose name includes 'do' and present the result list with 10 items per page.
|
|
897
|
+
Select all users whose name includes 'do' and present the result list with 10 items per page, sorted by surname.
|
|
897
898
|
```bash
|
|
898
|
-
curl -X GET 'http://localhost/myApp/users/?name.$re=do&_page=10'
|
|
899
|
+
curl -X GET 'http://localhost/myApp/users/?name.$re=do&_page=10&_sort=$.surname'
|
|
899
900
|
```
|
|
900
901
|
|
|
901
902
|
#### GET \<my-app-name\>/\<collection name\>/\<_id\>/\<path\>
|
|
@@ -1479,6 +1480,11 @@ log = log_system.get_or_create_logger("custom")
|
|
|
1479
1480
|
log.setLevel(logging.DEBUG)
|
|
1480
1481
|
log.addHandler ( my_own_handler )
|
|
1481
1482
|
# ...
|
|
1483
|
+
|
|
1484
|
+
# To see
|
|
1485
|
+
log_system.infos()
|
|
1486
|
+
# print some available informations about log system (levels, handlers)
|
|
1487
|
+
|
|
1482
1488
|
```
|
|
1483
1489
|
|
|
1484
1490
|
### stack()
|
|
@@ -1554,7 +1560,7 @@ def transform_function( o: dict) -> dict:
|
|
|
1554
1560
|
```
|
|
1555
1561
|
|
|
1556
1562
|
|
|
1557
|
-
By default, the
|
|
1563
|
+
By default, the strategy for migration is ```MigrationStrategy.DRY_RUN```. So you will broke nothing. ```MigrationStrategy.DRY_RUN``` will do all work except saving the object in the DB.
|
|
1558
1564
|
|
|
1559
1565
|
> [!IMPORTANT]
|
|
1560
1566
|
> there is no check of *rights* and *current_user* during migration. metadatas (see [_meta](#_meta)) are not updated.
|
|
@@ -1571,7 +1577,7 @@ This is an example for migrating data.
|
|
|
1571
1577
|
|
|
1572
1578
|
```python
|
|
1573
1579
|
from media_library import mybackoffice
|
|
1574
|
-
from backo import log_system, LogLevel
|
|
1580
|
+
from backo import log_system, LogLevel, MigrationStrategy
|
|
1575
1581
|
|
|
1576
1582
|
# Set migration level to debug
|
|
1577
1583
|
log_migration = log_system.get_or_create_logger("migration")
|
|
@@ -1611,13 +1617,24 @@ report = mybackoffice.migrate("books", update_with_note) # All ids
|
|
|
1611
1617
|
report = mybackoffice.migrate("books", update_with_note, _id="my_book_id", dry_run=False)
|
|
1612
1618
|
# or
|
|
1613
1619
|
report = mybackoffice.migrate(
|
|
1614
|
-
"books", update_with_note, _ids=["my_book_id1", "my_book_id2"],
|
|
1620
|
+
"books", update_with_note, _ids=["my_book_id1", "my_book_id2"], strategy=MigrationStrategy.EXECUTE
|
|
1615
1621
|
)
|
|
1616
1622
|
# or
|
|
1617
|
-
report = mybackoffice.migrate("books", update_with_note,
|
|
1623
|
+
report = mybackoffice.migrate("books", update_with_note, strategy=MigrationStrategy.EXECUTE) # All ids
|
|
1618
1624
|
|
|
1619
1625
|
```
|
|
1620
1626
|
|
|
1627
|
+
### MigrationStrategy options
|
|
1628
|
+
|
|
1629
|
+
| option | description |
|
|
1630
|
+
| - | - |
|
|
1631
|
+
| ```MigrationStrategy.DRY_RUN``` | Don't change anything, just display and report diffs |
|
|
1632
|
+
| ```MigrationStrategy.EXECUTE``` | Do changements and save in DB if needed. report diffs |
|
|
1633
|
+
| ```MigrationStrategy.FORCE``` | Do changements and rewrite data in DB. report diffs |
|
|
1634
|
+
|
|
1635
|
+
|
|
1636
|
+
|
|
1637
|
+
|
|
1621
1638
|
### report
|
|
1622
1639
|
|
|
1623
1640
|
The migration returns a report structure :
|
|
@@ -830,6 +830,7 @@ Get a list of objects matching the query string. The query string can be with th
|
|
|
830
830
|
| \_view | string | "client" | selects the view ([stricto views](https://github.com/backo-stricto/stricto?tab=readme-ov-file#views)) |
|
|
831
831
|
| \_page | int | - | sets the desired number of items per page in paginated data presentation |
|
|
832
832
|
| \_skip | int | - | skips the n-first items of the result list in paginated data presentation. |
|
|
833
|
+
| \_sort | string | - | give the list of sorting fields |
|
|
833
834
|
| \_total | whatyouwant | None | Just compute the total of object and return { 'total' : x } without taking pagination in account |
|
|
834
835
|
|
|
835
836
|
|
|
@@ -845,9 +846,9 @@ The request returns a HTTP status `200` with that JSON object:
|
|
|
845
846
|
```
|
|
846
847
|
|
|
847
848
|
##### Example
|
|
848
|
-
Select all users whose name includes 'do' and present the result list with 10 items per page.
|
|
849
|
+
Select all users whose name includes 'do' and present the result list with 10 items per page, sorted by surname.
|
|
849
850
|
```bash
|
|
850
|
-
curl -X GET 'http://localhost/myApp/users/?name.$re=do&_page=10'
|
|
851
|
+
curl -X GET 'http://localhost/myApp/users/?name.$re=do&_page=10&_sort=$.surname'
|
|
851
852
|
```
|
|
852
853
|
|
|
853
854
|
#### GET \<my-app-name\>/\<collection name\>/\<_id\>/\<path\>
|
|
@@ -1431,6 +1432,11 @@ log = log_system.get_or_create_logger("custom")
|
|
|
1431
1432
|
log.setLevel(logging.DEBUG)
|
|
1432
1433
|
log.addHandler ( my_own_handler )
|
|
1433
1434
|
# ...
|
|
1435
|
+
|
|
1436
|
+
# To see
|
|
1437
|
+
log_system.infos()
|
|
1438
|
+
# print some available informations about log system (levels, handlers)
|
|
1439
|
+
|
|
1434
1440
|
```
|
|
1435
1441
|
|
|
1436
1442
|
### stack()
|
|
@@ -1506,7 +1512,7 @@ def transform_function( o: dict) -> dict:
|
|
|
1506
1512
|
```
|
|
1507
1513
|
|
|
1508
1514
|
|
|
1509
|
-
By default, the
|
|
1515
|
+
By default, the strategy for migration is ```MigrationStrategy.DRY_RUN```. So you will broke nothing. ```MigrationStrategy.DRY_RUN``` will do all work except saving the object in the DB.
|
|
1510
1516
|
|
|
1511
1517
|
> [!IMPORTANT]
|
|
1512
1518
|
> there is no check of *rights* and *current_user* during migration. metadatas (see [_meta](#_meta)) are not updated.
|
|
@@ -1523,7 +1529,7 @@ This is an example for migrating data.
|
|
|
1523
1529
|
|
|
1524
1530
|
```python
|
|
1525
1531
|
from media_library import mybackoffice
|
|
1526
|
-
from backo import log_system, LogLevel
|
|
1532
|
+
from backo import log_system, LogLevel, MigrationStrategy
|
|
1527
1533
|
|
|
1528
1534
|
# Set migration level to debug
|
|
1529
1535
|
log_migration = log_system.get_or_create_logger("migration")
|
|
@@ -1563,13 +1569,24 @@ report = mybackoffice.migrate("books", update_with_note) # All ids
|
|
|
1563
1569
|
report = mybackoffice.migrate("books", update_with_note, _id="my_book_id", dry_run=False)
|
|
1564
1570
|
# or
|
|
1565
1571
|
report = mybackoffice.migrate(
|
|
1566
|
-
"books", update_with_note, _ids=["my_book_id1", "my_book_id2"],
|
|
1572
|
+
"books", update_with_note, _ids=["my_book_id1", "my_book_id2"], strategy=MigrationStrategy.EXECUTE
|
|
1567
1573
|
)
|
|
1568
1574
|
# or
|
|
1569
|
-
report = mybackoffice.migrate("books", update_with_note,
|
|
1575
|
+
report = mybackoffice.migrate("books", update_with_note, strategy=MigrationStrategy.EXECUTE) # All ids
|
|
1570
1576
|
|
|
1571
1577
|
```
|
|
1572
1578
|
|
|
1579
|
+
### MigrationStrategy options
|
|
1580
|
+
|
|
1581
|
+
| option | description |
|
|
1582
|
+
| - | - |
|
|
1583
|
+
| ```MigrationStrategy.DRY_RUN``` | Don't change anything, just display and report diffs |
|
|
1584
|
+
| ```MigrationStrategy.EXECUTE``` | Do changements and save in DB if needed. report diffs |
|
|
1585
|
+
| ```MigrationStrategy.FORCE``` | Do changements and rewrite data in DB. report diffs |
|
|
1586
|
+
|
|
1587
|
+
|
|
1588
|
+
|
|
1589
|
+
|
|
1573
1590
|
### report
|
|
1574
1591
|
|
|
1575
1592
|
The migration returns a report structure :
|
|
@@ -20,6 +20,7 @@ from .error import (
|
|
|
20
20
|
BackoError,
|
|
21
21
|
SessionError,
|
|
22
22
|
FileError,
|
|
23
|
+
ExpiredError,
|
|
23
24
|
)
|
|
24
25
|
from .backoffice import Backoffice
|
|
25
26
|
from .collection import Collection
|
|
@@ -37,7 +38,7 @@ from .file.blob_file import BlobFile
|
|
|
37
38
|
from .meta_data_handler import GenericMetaDataHandler, StandardMetaDataHandler
|
|
38
39
|
from .status import StatusType
|
|
39
40
|
from .action import Action
|
|
40
|
-
from .
|
|
41
|
+
from .migration import MigrationReport, MigrationStrategy
|
|
41
42
|
from .request_decorators import (
|
|
42
43
|
check_content_type,
|
|
43
44
|
return_http_error,
|
|
@@ -48,4 +49,5 @@ from .api_toolbox import (
|
|
|
48
49
|
multidict_to_sfilter,
|
|
49
50
|
dict_to_sfilter,
|
|
50
51
|
)
|
|
52
|
+
from .sort import SortItem, Sort
|
|
51
53
|
from .initialisation.init_script import backo_init
|
|
@@ -15,7 +15,7 @@ from stricto import Kparse, SSyntaxError, validation_parameters
|
|
|
15
15
|
|
|
16
16
|
from .collection import Collection
|
|
17
17
|
from .item import Item
|
|
18
|
-
from .
|
|
18
|
+
from .migration import MigrationReport, MigrationStrategy
|
|
19
19
|
from .log import log_system
|
|
20
20
|
from .openapi import BACKO_FILTER_SCHEMA, BACKO_META_SCHEMA, JSON_PATCH_SCHEMA
|
|
21
21
|
from .request_decorators import error_to_http_handler
|
|
@@ -27,6 +27,7 @@ KPARSE_MIGRATION_MODEL = {
|
|
|
27
27
|
"_id": str,
|
|
28
28
|
"_ids": list[str],
|
|
29
29
|
"dry_run": {"type": bool, "default": True},
|
|
30
|
+
"strategy": {"type": MigrationStrategy, "default": MigrationStrategy.DRY_RUN},
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
|
|
@@ -56,9 +57,9 @@ class Backoffice: # pylint: disable=too-many-instance-attributes
|
|
|
56
57
|
def __init__(self, name: str):
|
|
57
58
|
"""Constructor for backoffice"""
|
|
58
59
|
self.name = name
|
|
59
|
-
self.collections = {}
|
|
60
|
+
self.collections: dict[str, Collection] = {}
|
|
60
61
|
self._transaction_id_reference = 1
|
|
61
|
-
self.transactions = {}
|
|
62
|
+
self.transactions: dict[int, list[Transaction]] = {}
|
|
62
63
|
|
|
63
64
|
@validation_parameters
|
|
64
65
|
def register_collection(self, coll: Collection) -> None:
|
|
@@ -169,8 +170,15 @@ class Backoffice: # pylint: disable=too-many-instance-attributes
|
|
|
169
170
|
if _ids is None and options.get("_id") is not None:
|
|
170
171
|
_ids = [options.get("_id")]
|
|
171
172
|
|
|
173
|
+
strategy: MigrationStrategy = options.get("strategy")
|
|
174
|
+
if strategy not in MigrationStrategy:
|
|
175
|
+
raise SSyntaxError(
|
|
176
|
+
'Migration Strategy "{0}" not found',
|
|
177
|
+
strategy,
|
|
178
|
+
)
|
|
179
|
+
|
|
172
180
|
coll = self.collections.get(collection_name)
|
|
173
|
-
return coll.migrate(migration_function, _ids,
|
|
181
|
+
return coll.migrate(migration_function, _ids, strategy)
|
|
174
182
|
|
|
175
183
|
@validation_parameters
|
|
176
184
|
def build_routes(
|