sqlalchemyseed 2.0.0__tar.gz → 2.2.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.
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/PKG-INFO +61 -21
- sqlalchemyseed-2.0.0/src/sqlalchemyseed.egg-info/PKG-INFO → sqlalchemyseed-2.2.0/README.md +48 -33
- sqlalchemyseed-2.2.0/pyproject.toml +57 -0
- sqlalchemyseed-2.2.0/setup.cfg +4 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed/__init__.py +1 -1
- sqlalchemyseed-2.2.0/src/sqlalchemyseed/__main__.py +6 -0
- sqlalchemyseed-2.2.0/src/sqlalchemyseed/cli.py +169 -0
- sqlalchemyseed-2.2.0/src/sqlalchemyseed.egg-info/PKG-INFO +177 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed.egg-info/SOURCES.txt +4 -2
- sqlalchemyseed-2.2.0/src/sqlalchemyseed.egg-info/entry_points.txt +2 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed.egg-info/requires.txt +1 -1
- sqlalchemyseed-2.2.0/tests/test_cli.py +133 -0
- sqlalchemyseed-2.0.0/README.md +0 -114
- sqlalchemyseed-2.0.0/pyproject.toml +0 -6
- sqlalchemyseed-2.0.0/setup.cfg +0 -44
- sqlalchemyseed-2.0.0/setup.py +0 -4
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/LICENSE +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed/_future/__init__.py +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed/_future/seeder.py +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed/attribute.py +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed/constants.py +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed/dynamic_seeder.py +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed/errors.py +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed/json.py +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed/loader.py +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed/seeder.py +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed/util.py +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed/validator.py +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed.egg-info/dependency_links.txt +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed.egg-info/top_level.txt +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/tests/test_json.py +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/tests/test_loader.py +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/tests/test_seeder.py +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/tests/test_temp_seeder.py +0 -0
- {sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/tests/test_validator.py +0 -0
|
@@ -1,25 +1,27 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlalchemyseed
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: SQLAlchemy Seeder
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
License: MIT
|
|
5
|
+
Author-email: Jedy Matt Tabasco <hello@jedymatt.dev>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/jedymatt/sqlalchemyseed
|
|
9
8
|
Project-URL: Documentation, https://sqlalchemyseed.readthedocs.io/
|
|
10
9
|
Project-URL: Source, https://github.com/jedymatt/sqlalchemyseed
|
|
11
10
|
Project-URL: Tracker, https://github.com/jedymatt/sqlalchemyseed/issues
|
|
12
11
|
Keywords: sqlalchemy,orm,seed,seeder,json,yaml
|
|
13
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
16
12
|
Classifier: Programming Language :: Python :: 3.9
|
|
17
13
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
14
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
-
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Requires-Python: >=3.9
|
|
20
19
|
Description-Content-Type: text/markdown
|
|
21
|
-
Provides-Extra: yaml
|
|
22
20
|
License-File: LICENSE
|
|
21
|
+
Requires-Dist: SQLAlchemy>=2.0
|
|
22
|
+
Provides-Extra: yaml
|
|
23
|
+
Requires-Dist: PyYAML>=6.0; extra == "yaml"
|
|
24
|
+
Dynamic: license-file
|
|
23
25
|
|
|
24
26
|
# sqlalchemyseed
|
|
25
27
|
|
|
@@ -87,6 +89,40 @@ data.json
|
|
|
87
89
|
}
|
|
88
90
|
```
|
|
89
91
|
|
|
92
|
+
## Command-line usage
|
|
93
|
+
|
|
94
|
+
Seed a database directly from data files without writing Python:
|
|
95
|
+
|
|
96
|
+
```shell
|
|
97
|
+
sqlalchemyseed data.json --url sqlite:///app.db
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The command accepts one or more files and/or directories (a directory seeds
|
|
101
|
+
every `.json`/`.yaml`/`.yml` file inside it, in sorted order):
|
|
102
|
+
|
|
103
|
+
```shell
|
|
104
|
+
sqlalchemyseed seeds/ --url "$DATABASE_URL"
|
|
105
|
+
sqlalchemyseed a.json b.yaml --url sqlite:///app.db
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The database URL may be passed with `--url` or the `DATABASE_URL` environment
|
|
109
|
+
variable. Model paths in the data files (e.g. `models.Person`) are resolved
|
|
110
|
+
against the current working directory, so run the command from your project
|
|
111
|
+
root.
|
|
112
|
+
|
|
113
|
+
Options:
|
|
114
|
+
|
|
115
|
+
- `--dry-run` — seed inside a transaction, then roll back (validate without writing)
|
|
116
|
+
- `--seeder hybrid` — use `HybridSeeder` instead of the default `Seeder`
|
|
117
|
+
- `--model models.Person` — required for CSV inputs, which are not self-describing
|
|
118
|
+
- `--ref-prefix` — override the relationship reference prefix (default `!`)
|
|
119
|
+
|
|
120
|
+
The same command is available as a module:
|
|
121
|
+
|
|
122
|
+
```shell
|
|
123
|
+
python -m sqlalchemyseed data.json --url sqlite:///app.db
|
|
124
|
+
```
|
|
125
|
+
|
|
90
126
|
## Documentation
|
|
91
127
|
|
|
92
128
|
<https://sqlalchemyseed.readthedocs.io/>
|
|
@@ -100,34 +136,38 @@ Report here in this link:
|
|
|
100
136
|
|
|
101
137
|
First, Clone this [repository](https://github.com/jedymatt/sqlalchemyseed).
|
|
102
138
|
|
|
139
|
+
This project uses [uv](https://docs.astral.sh/uv/) for dependency management and running tasks.
|
|
140
|
+
|
|
103
141
|
### Install dev dependencies
|
|
104
142
|
|
|
105
|
-
Inside the folder,
|
|
143
|
+
Inside the folder, sync the environment (uv creates the virtualenv and installs the project plus dev dependencies):
|
|
106
144
|
|
|
107
145
|
```shell
|
|
108
|
-
|
|
146
|
+
uv sync
|
|
109
147
|
```
|
|
110
148
|
|
|
111
|
-
Note: make sure you have the virtual environment and enabled, or if you are using vs code and docker then you can simply re-open this as container.
|
|
112
|
-
|
|
113
149
|
### Run tests
|
|
114
150
|
|
|
115
|
-
|
|
151
|
+
```shell
|
|
152
|
+
uv run pytest
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Run the tests against a specific Python version (uv downloads it if needed):
|
|
116
156
|
|
|
117
157
|
```shell
|
|
118
|
-
python
|
|
158
|
+
uv run --python 3.14 pytest
|
|
119
159
|
```
|
|
120
160
|
|
|
121
|
-
|
|
161
|
+
Run the tests against the lowest supported dependencies (e.g. SQLAlchemy 2.0):
|
|
122
162
|
|
|
123
163
|
```shell
|
|
124
|
-
pytest
|
|
164
|
+
uv run --resolution lowest-direct pytest
|
|
125
165
|
```
|
|
126
166
|
|
|
127
|
-
Run
|
|
167
|
+
Run tests with coverage:
|
|
128
168
|
|
|
129
169
|
```shell
|
|
130
|
-
coverage run -m pytest
|
|
170
|
+
uv run coverage run -m pytest
|
|
131
171
|
```
|
|
132
172
|
|
|
133
173
|
Autobuild documentation
|
|
@@ -1,26 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: sqlalchemyseed
|
|
3
|
-
Version: 2.0.0
|
|
4
|
-
Summary: SQLAlchemy Seeder
|
|
5
|
-
Home-page: https://github.com/jedymatt/sqlalchemyseed
|
|
6
|
-
Author: Jedy Matt Tabasco
|
|
7
|
-
Author-email: jedymatt@gmail.com
|
|
8
|
-
License: MIT
|
|
9
|
-
Project-URL: Documentation, https://sqlalchemyseed.readthedocs.io/
|
|
10
|
-
Project-URL: Source, https://github.com/jedymatt/sqlalchemyseed
|
|
11
|
-
Project-URL: Tracker, https://github.com/jedymatt/sqlalchemyseed/issues
|
|
12
|
-
Keywords: sqlalchemy,orm,seed,seeder,json,yaml
|
|
13
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
-
Requires-Python: >=3.7
|
|
20
|
-
Description-Content-Type: text/markdown
|
|
21
|
-
Provides-Extra: yaml
|
|
22
|
-
License-File: LICENSE
|
|
23
|
-
|
|
24
1
|
# sqlalchemyseed
|
|
25
2
|
|
|
26
3
|
[](https://pypi.org/project/sqlalchemyseed)
|
|
@@ -87,6 +64,40 @@ data.json
|
|
|
87
64
|
}
|
|
88
65
|
```
|
|
89
66
|
|
|
67
|
+
## Command-line usage
|
|
68
|
+
|
|
69
|
+
Seed a database directly from data files without writing Python:
|
|
70
|
+
|
|
71
|
+
```shell
|
|
72
|
+
sqlalchemyseed data.json --url sqlite:///app.db
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The command accepts one or more files and/or directories (a directory seeds
|
|
76
|
+
every `.json`/`.yaml`/`.yml` file inside it, in sorted order):
|
|
77
|
+
|
|
78
|
+
```shell
|
|
79
|
+
sqlalchemyseed seeds/ --url "$DATABASE_URL"
|
|
80
|
+
sqlalchemyseed a.json b.yaml --url sqlite:///app.db
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The database URL may be passed with `--url` or the `DATABASE_URL` environment
|
|
84
|
+
variable. Model paths in the data files (e.g. `models.Person`) are resolved
|
|
85
|
+
against the current working directory, so run the command from your project
|
|
86
|
+
root.
|
|
87
|
+
|
|
88
|
+
Options:
|
|
89
|
+
|
|
90
|
+
- `--dry-run` — seed inside a transaction, then roll back (validate without writing)
|
|
91
|
+
- `--seeder hybrid` — use `HybridSeeder` instead of the default `Seeder`
|
|
92
|
+
- `--model models.Person` — required for CSV inputs, which are not self-describing
|
|
93
|
+
- `--ref-prefix` — override the relationship reference prefix (default `!`)
|
|
94
|
+
|
|
95
|
+
The same command is available as a module:
|
|
96
|
+
|
|
97
|
+
```shell
|
|
98
|
+
python -m sqlalchemyseed data.json --url sqlite:///app.db
|
|
99
|
+
```
|
|
100
|
+
|
|
90
101
|
## Documentation
|
|
91
102
|
|
|
92
103
|
<https://sqlalchemyseed.readthedocs.io/>
|
|
@@ -100,34 +111,38 @@ Report here in this link:
|
|
|
100
111
|
|
|
101
112
|
First, Clone this [repository](https://github.com/jedymatt/sqlalchemyseed).
|
|
102
113
|
|
|
114
|
+
This project uses [uv](https://docs.astral.sh/uv/) for dependency management and running tasks.
|
|
115
|
+
|
|
103
116
|
### Install dev dependencies
|
|
104
117
|
|
|
105
|
-
Inside the folder,
|
|
118
|
+
Inside the folder, sync the environment (uv creates the virtualenv and installs the project plus dev dependencies):
|
|
106
119
|
|
|
107
120
|
```shell
|
|
108
|
-
|
|
121
|
+
uv sync
|
|
109
122
|
```
|
|
110
123
|
|
|
111
|
-
Note: make sure you have the virtual environment and enabled, or if you are using vs code and docker then you can simply re-open this as container.
|
|
112
|
-
|
|
113
124
|
### Run tests
|
|
114
125
|
|
|
115
|
-
|
|
126
|
+
```shell
|
|
127
|
+
uv run pytest
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Run the tests against a specific Python version (uv downloads it if needed):
|
|
116
131
|
|
|
117
132
|
```shell
|
|
118
|
-
python
|
|
133
|
+
uv run --python 3.14 pytest
|
|
119
134
|
```
|
|
120
135
|
|
|
121
|
-
|
|
136
|
+
Run the tests against the lowest supported dependencies (e.g. SQLAlchemy 2.0):
|
|
122
137
|
|
|
123
138
|
```shell
|
|
124
|
-
pytest
|
|
139
|
+
uv run --resolution lowest-direct pytest
|
|
125
140
|
```
|
|
126
141
|
|
|
127
|
-
Run
|
|
142
|
+
Run tests with coverage:
|
|
128
143
|
|
|
129
144
|
```shell
|
|
130
|
-
coverage run -m pytest
|
|
145
|
+
uv run coverage run -m pytest
|
|
131
146
|
```
|
|
132
147
|
|
|
133
148
|
Autobuild documentation
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "sqlalchemyseed"
|
|
3
|
+
description = "SQLAlchemy Seeder"
|
|
4
|
+
readme = "README.md"
|
|
5
|
+
requires-python = ">=3.9"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "Jedy Matt Tabasco", email = "hello@jedymatt.dev" },
|
|
10
|
+
]
|
|
11
|
+
keywords = ["sqlalchemy", "orm", "seed", "seeder", "json", "yaml"]
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Programming Language :: Python :: 3.9",
|
|
14
|
+
"Programming Language :: Python :: 3.10",
|
|
15
|
+
"Programming Language :: Python :: 3.11",
|
|
16
|
+
"Programming Language :: Python :: 3.12",
|
|
17
|
+
"Programming Language :: Python :: 3.13",
|
|
18
|
+
"Programming Language :: Python :: 3.14",
|
|
19
|
+
]
|
|
20
|
+
dependencies = [
|
|
21
|
+
"SQLAlchemy>=2.0",
|
|
22
|
+
]
|
|
23
|
+
dynamic = ["version"]
|
|
24
|
+
|
|
25
|
+
[project.optional-dependencies]
|
|
26
|
+
yaml = [
|
|
27
|
+
"PyYAML>=6.0",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.scripts]
|
|
31
|
+
sqlalchemyseed = "sqlalchemyseed.cli:main"
|
|
32
|
+
|
|
33
|
+
[project.urls]
|
|
34
|
+
Homepage = "https://github.com/jedymatt/sqlalchemyseed"
|
|
35
|
+
Documentation = "https://sqlalchemyseed.readthedocs.io/"
|
|
36
|
+
Source = "https://github.com/jedymatt/sqlalchemyseed"
|
|
37
|
+
Tracker = "https://github.com/jedymatt/sqlalchemyseed/issues"
|
|
38
|
+
|
|
39
|
+
[dependency-groups]
|
|
40
|
+
dev = [
|
|
41
|
+
"pytest>=7.0",
|
|
42
|
+
"coverage>=6.2",
|
|
43
|
+
"PyYAML>=6.0",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[build-system]
|
|
47
|
+
requires = ["setuptools>=77"]
|
|
48
|
+
build-backend = "setuptools.build_meta"
|
|
49
|
+
|
|
50
|
+
[tool.setuptools.dynamic]
|
|
51
|
+
version = { attr = "sqlalchemyseed.__version__" }
|
|
52
|
+
|
|
53
|
+
[tool.setuptools.packages.find]
|
|
54
|
+
where = ["src"]
|
|
55
|
+
|
|
56
|
+
[tool.uv]
|
|
57
|
+
default-groups = ["dev"]
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"""Command-line interface for seeding a database from data files."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import sqlalchemy
|
|
9
|
+
from sqlalchemy.orm import Session
|
|
10
|
+
|
|
11
|
+
from . import loader
|
|
12
|
+
from .seeder import HybridSeeder, Seeder
|
|
13
|
+
|
|
14
|
+
_JSON_EXTENSIONS = {".json"}
|
|
15
|
+
_YAML_EXTENSIONS = {".yaml", ".yml"}
|
|
16
|
+
_CSV_EXTENSIONS = {".csv"}
|
|
17
|
+
# Only self-describing formats are auto-discovered inside a directory. CSV
|
|
18
|
+
# needs an explicit --model, so a CSV must be named as an individual file.
|
|
19
|
+
_DISCOVERABLE_EXTENSIONS = _JSON_EXTENSIONS | _YAML_EXTENSIONS
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
23
|
+
"""Build the argument parser for the ``sqlalchemyseed`` command."""
|
|
24
|
+
parser = argparse.ArgumentParser(
|
|
25
|
+
prog="sqlalchemyseed",
|
|
26
|
+
description="Seed a database from JSON, YAML, or CSV data files.",
|
|
27
|
+
)
|
|
28
|
+
parser.add_argument(
|
|
29
|
+
"paths",
|
|
30
|
+
nargs="+",
|
|
31
|
+
metavar="PATH",
|
|
32
|
+
help="data files or directories to seed from",
|
|
33
|
+
)
|
|
34
|
+
parser.add_argument(
|
|
35
|
+
"--url",
|
|
36
|
+
help="SQLAlchemy database URL (defaults to the DATABASE_URL env var)",
|
|
37
|
+
)
|
|
38
|
+
parser.add_argument(
|
|
39
|
+
"--seeder",
|
|
40
|
+
choices=("basic", "hybrid"),
|
|
41
|
+
default="basic",
|
|
42
|
+
help="seeder to use (default: basic)",
|
|
43
|
+
)
|
|
44
|
+
parser.add_argument(
|
|
45
|
+
"--model",
|
|
46
|
+
help="model class path (e.g. models.Person) required for CSV inputs",
|
|
47
|
+
)
|
|
48
|
+
parser.add_argument(
|
|
49
|
+
"--ref-prefix",
|
|
50
|
+
default="!",
|
|
51
|
+
help="prefix marking relationship references (default: !)",
|
|
52
|
+
)
|
|
53
|
+
parser.add_argument(
|
|
54
|
+
"--dry-run",
|
|
55
|
+
action="store_true",
|
|
56
|
+
help="seed within a transaction but roll back instead of committing",
|
|
57
|
+
)
|
|
58
|
+
return parser
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def collect_files(paths) -> list:
|
|
62
|
+
"""Expand each path into data files, walking directories in sorted order."""
|
|
63
|
+
files = []
|
|
64
|
+
for raw_path in paths:
|
|
65
|
+
files.extend(_files_in(Path(raw_path)))
|
|
66
|
+
return files
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _files_in(path: Path) -> list:
|
|
70
|
+
"""Return the data files contributed by a single path argument."""
|
|
71
|
+
if path.is_dir():
|
|
72
|
+
return _discover_directory(path)
|
|
73
|
+
if path.is_file():
|
|
74
|
+
return [path]
|
|
75
|
+
raise FileNotFoundError(f"path does not exist: {path}")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _discover_directory(directory: Path) -> list:
|
|
79
|
+
"""Return the JSON/YAML files inside a directory, sorted by name."""
|
|
80
|
+
discovered = sorted(
|
|
81
|
+
child for child in directory.iterdir()
|
|
82
|
+
if child.suffix.lower() in _DISCOVERABLE_EXTENSIONS
|
|
83
|
+
)
|
|
84
|
+
if not discovered:
|
|
85
|
+
raise FileNotFoundError(
|
|
86
|
+
f"no JSON or YAML seed files found in directory: {directory}"
|
|
87
|
+
)
|
|
88
|
+
return discovered
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def load_file(path: Path, model=None) -> dict:
|
|
92
|
+
"""Load entities from a single data file, dispatching on its extension."""
|
|
93
|
+
suffix = path.suffix.lower()
|
|
94
|
+
if suffix in _JSON_EXTENSIONS:
|
|
95
|
+
return loader.load_entities_from_json(str(path))
|
|
96
|
+
if suffix in _YAML_EXTENSIONS:
|
|
97
|
+
return loader.load_entities_from_yaml(str(path))
|
|
98
|
+
if suffix in _CSV_EXTENSIONS:
|
|
99
|
+
return _load_csv(path, model)
|
|
100
|
+
raise ValueError(f"unsupported file type: {path}")
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _load_csv(path: Path, model) -> dict:
|
|
104
|
+
"""Load entities from a CSV file, which requires an explicit model."""
|
|
105
|
+
if model is None:
|
|
106
|
+
raise ValueError(f"CSV input requires --model to name the target class: {path}")
|
|
107
|
+
return loader.load_entities_from_csv(str(path), model)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _make_seeder(name, session, ref_prefix):
|
|
111
|
+
"""Return the seeder implementation selected on the command line."""
|
|
112
|
+
if name == "hybrid":
|
|
113
|
+
return HybridSeeder(session, ref_prefix=ref_prefix)
|
|
114
|
+
return Seeder(session, ref_prefix=ref_prefix)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _seed_all(seeder, files, model) -> int:
|
|
118
|
+
"""Seed every file through the seeder and return the entity count."""
|
|
119
|
+
seeded = 0
|
|
120
|
+
for path in files:
|
|
121
|
+
seeder.seed(load_file(path, model))
|
|
122
|
+
seeded += len(seeder.instances)
|
|
123
|
+
return seeded
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def main(argv=None) -> int:
|
|
127
|
+
"""Entry point for the ``sqlalchemyseed`` command."""
|
|
128
|
+
parser = build_parser()
|
|
129
|
+
args = parser.parse_args(argv)
|
|
130
|
+
|
|
131
|
+
url = args.url or os.environ.get("DATABASE_URL")
|
|
132
|
+
if not url:
|
|
133
|
+
parser.error("a database URL is required via --url or the DATABASE_URL env var")
|
|
134
|
+
|
|
135
|
+
# Make the caller's project importable so model paths like "models.Person"
|
|
136
|
+
# resolve against the current working directory.
|
|
137
|
+
sys.path.insert(0, os.getcwd())
|
|
138
|
+
|
|
139
|
+
try:
|
|
140
|
+
files = collect_files(args.paths)
|
|
141
|
+
except FileNotFoundError as error:
|
|
142
|
+
parser.error(str(error))
|
|
143
|
+
|
|
144
|
+
engine = sqlalchemy.create_engine(url)
|
|
145
|
+
with Session(engine) as session:
|
|
146
|
+
seeder = _make_seeder(args.seeder, session, args.ref_prefix)
|
|
147
|
+
try:
|
|
148
|
+
seeded = _seed_all(seeder, files, args.model)
|
|
149
|
+
except Exception as error: # noqa: BLE001 - report any seeding failure as a clean exit
|
|
150
|
+
session.rollback()
|
|
151
|
+
print(f"error: {error}", file=sys.stderr)
|
|
152
|
+
return 1
|
|
153
|
+
|
|
154
|
+
return _finish(session, seeded, len(files), args.dry_run)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _finish(session, seeded, file_count, dry_run) -> int:
|
|
158
|
+
"""Commit or roll back the seeded session and print a summary."""
|
|
159
|
+
if dry_run:
|
|
160
|
+
session.rollback()
|
|
161
|
+
print(f"Dry run: would seed {seeded} entities from {file_count} file(s) (rolled back).")
|
|
162
|
+
return 0
|
|
163
|
+
session.commit()
|
|
164
|
+
print(f"Seeded {seeded} entities from {file_count} file(s).")
|
|
165
|
+
return 0
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
if __name__ == "__main__": # pragma: no cover
|
|
169
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sqlalchemyseed
|
|
3
|
+
Version: 2.2.0
|
|
4
|
+
Summary: SQLAlchemy Seeder
|
|
5
|
+
Author-email: Jedy Matt Tabasco <hello@jedymatt.dev>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/jedymatt/sqlalchemyseed
|
|
8
|
+
Project-URL: Documentation, https://sqlalchemyseed.readthedocs.io/
|
|
9
|
+
Project-URL: Source, https://github.com/jedymatt/sqlalchemyseed
|
|
10
|
+
Project-URL: Tracker, https://github.com/jedymatt/sqlalchemyseed/issues
|
|
11
|
+
Keywords: sqlalchemy,orm,seed,seeder,json,yaml
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: SQLAlchemy>=2.0
|
|
22
|
+
Provides-Extra: yaml
|
|
23
|
+
Requires-Dist: PyYAML>=6.0; extra == "yaml"
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# sqlalchemyseed
|
|
27
|
+
|
|
28
|
+
[](https://pypi.org/project/sqlalchemyseed)
|
|
29
|
+
[](https://pypi.org/project/sqlalchemyseed)
|
|
30
|
+
[](https://github.com/jedymatt/sqlalchemyseed/blob/main/LICENSE)
|
|
31
|
+
[](https://github.com/jedymatt/sqlalchemyseed/actions/workflows/python-package.yml)
|
|
32
|
+
[](https://codeclimate.com/github/jedymatt/sqlalchemyseed/maintainability)
|
|
33
|
+
[](https://codecov.io/gh/jedymatt/sqlalchemyseed)
|
|
34
|
+
[](https://sqlalchemyseed.readthedocs.io/en/latest/?badge=latest)
|
|
35
|
+
|
|
36
|
+
Sqlalchemy seeder that supports nested relationships.
|
|
37
|
+
|
|
38
|
+
Supported file types
|
|
39
|
+
|
|
40
|
+
- json
|
|
41
|
+
- yaml
|
|
42
|
+
- csv
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
Default installation
|
|
47
|
+
|
|
48
|
+
```shell
|
|
49
|
+
pip install sqlalchemyseed
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Quickstart
|
|
53
|
+
|
|
54
|
+
main.py
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from sqlalchemyseed import load_entities_from_json
|
|
58
|
+
from sqlalchemyseed import Seeder
|
|
59
|
+
from db import session
|
|
60
|
+
|
|
61
|
+
# load entities
|
|
62
|
+
entities = load_entities_from_json('data.json')
|
|
63
|
+
|
|
64
|
+
# Initializing Seeder
|
|
65
|
+
seeder = Seeder(session)
|
|
66
|
+
|
|
67
|
+
# Seeding
|
|
68
|
+
seeder.seed(entities)
|
|
69
|
+
|
|
70
|
+
# Committing
|
|
71
|
+
session.commit() # or seeder.session.commit()
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
data.json
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"model": "models.Person",
|
|
79
|
+
"data": [
|
|
80
|
+
{
|
|
81
|
+
"name": "John March",
|
|
82
|
+
"age": 23
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"name": "Juan Dela Cruz",
|
|
86
|
+
"age": 21
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Command-line usage
|
|
93
|
+
|
|
94
|
+
Seed a database directly from data files without writing Python:
|
|
95
|
+
|
|
96
|
+
```shell
|
|
97
|
+
sqlalchemyseed data.json --url sqlite:///app.db
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The command accepts one or more files and/or directories (a directory seeds
|
|
101
|
+
every `.json`/`.yaml`/`.yml` file inside it, in sorted order):
|
|
102
|
+
|
|
103
|
+
```shell
|
|
104
|
+
sqlalchemyseed seeds/ --url "$DATABASE_URL"
|
|
105
|
+
sqlalchemyseed a.json b.yaml --url sqlite:///app.db
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The database URL may be passed with `--url` or the `DATABASE_URL` environment
|
|
109
|
+
variable. Model paths in the data files (e.g. `models.Person`) are resolved
|
|
110
|
+
against the current working directory, so run the command from your project
|
|
111
|
+
root.
|
|
112
|
+
|
|
113
|
+
Options:
|
|
114
|
+
|
|
115
|
+
- `--dry-run` — seed inside a transaction, then roll back (validate without writing)
|
|
116
|
+
- `--seeder hybrid` — use `HybridSeeder` instead of the default `Seeder`
|
|
117
|
+
- `--model models.Person` — required for CSV inputs, which are not self-describing
|
|
118
|
+
- `--ref-prefix` — override the relationship reference prefix (default `!`)
|
|
119
|
+
|
|
120
|
+
The same command is available as a module:
|
|
121
|
+
|
|
122
|
+
```shell
|
|
123
|
+
python -m sqlalchemyseed data.json --url sqlite:///app.db
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Documentation
|
|
127
|
+
|
|
128
|
+
<https://sqlalchemyseed.readthedocs.io/>
|
|
129
|
+
|
|
130
|
+
## Found Bug?
|
|
131
|
+
|
|
132
|
+
Report here in this link:
|
|
133
|
+
<https://github.com/jedymatt/sqlalchemyseed/issues>
|
|
134
|
+
|
|
135
|
+
## Want to contribute?
|
|
136
|
+
|
|
137
|
+
First, Clone this [repository](https://github.com/jedymatt/sqlalchemyseed).
|
|
138
|
+
|
|
139
|
+
This project uses [uv](https://docs.astral.sh/uv/) for dependency management and running tasks.
|
|
140
|
+
|
|
141
|
+
### Install dev dependencies
|
|
142
|
+
|
|
143
|
+
Inside the folder, sync the environment (uv creates the virtualenv and installs the project plus dev dependencies):
|
|
144
|
+
|
|
145
|
+
```shell
|
|
146
|
+
uv sync
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Run tests
|
|
150
|
+
|
|
151
|
+
```shell
|
|
152
|
+
uv run pytest
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Run the tests against a specific Python version (uv downloads it if needed):
|
|
156
|
+
|
|
157
|
+
```shell
|
|
158
|
+
uv run --python 3.14 pytest
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Run the tests against the lowest supported dependencies (e.g. SQLAlchemy 2.0):
|
|
162
|
+
|
|
163
|
+
```shell
|
|
164
|
+
uv run --resolution lowest-direct pytest
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Run tests with coverage:
|
|
168
|
+
|
|
169
|
+
```shell
|
|
170
|
+
uv run coverage run -m pytest
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Autobuild documentation
|
|
174
|
+
|
|
175
|
+
```shell
|
|
176
|
+
sphinx-autobuild docs docs/_build/html
|
|
177
|
+
```
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
LICENSE
|
|
2
2
|
README.md
|
|
3
3
|
pyproject.toml
|
|
4
|
-
setup.cfg
|
|
5
|
-
setup.py
|
|
6
4
|
src/sqlalchemyseed/__init__.py
|
|
5
|
+
src/sqlalchemyseed/__main__.py
|
|
7
6
|
src/sqlalchemyseed/attribute.py
|
|
7
|
+
src/sqlalchemyseed/cli.py
|
|
8
8
|
src/sqlalchemyseed/constants.py
|
|
9
9
|
src/sqlalchemyseed/dynamic_seeder.py
|
|
10
10
|
src/sqlalchemyseed/errors.py
|
|
@@ -16,10 +16,12 @@ src/sqlalchemyseed/validator.py
|
|
|
16
16
|
src/sqlalchemyseed.egg-info/PKG-INFO
|
|
17
17
|
src/sqlalchemyseed.egg-info/SOURCES.txt
|
|
18
18
|
src/sqlalchemyseed.egg-info/dependency_links.txt
|
|
19
|
+
src/sqlalchemyseed.egg-info/entry_points.txt
|
|
19
20
|
src/sqlalchemyseed.egg-info/requires.txt
|
|
20
21
|
src/sqlalchemyseed.egg-info/top_level.txt
|
|
21
22
|
src/sqlalchemyseed/_future/__init__.py
|
|
22
23
|
src/sqlalchemyseed/_future/seeder.py
|
|
24
|
+
tests/test_cli.py
|
|
23
25
|
tests/test_json.py
|
|
24
26
|
tests/test_loader.py
|
|
25
27
|
tests/test_seeder.py
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"""Tests for the sqlalchemyseed command-line interface."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
from sqlalchemy import create_engine
|
|
7
|
+
from sqlalchemy.orm import Session
|
|
8
|
+
|
|
9
|
+
from sqlalchemyseed import cli
|
|
10
|
+
from tests.models import Base, Person
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@pytest.fixture
|
|
14
|
+
def db_url(tmp_path):
|
|
15
|
+
"""A file-backed SQLite URL with the test schema already created."""
|
|
16
|
+
url = f"sqlite:///{tmp_path / 'seed.db'}"
|
|
17
|
+
engine = create_engine(url)
|
|
18
|
+
Base.metadata.create_all(engine)
|
|
19
|
+
engine.dispose()
|
|
20
|
+
return url
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def count_persons(url):
|
|
24
|
+
with Session(create_engine(url)) as session:
|
|
25
|
+
return session.query(Person).count()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def write_json(path, entities):
|
|
29
|
+
path.write_text(json.dumps(entities), encoding="utf-8")
|
|
30
|
+
return path
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def person_entities(*names):
|
|
34
|
+
return {"model": "tests.models.Person", "data": [{"name": name} for name in names]}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def test_seed_json_file(tmp_path, db_url):
|
|
38
|
+
data_file = write_json(tmp_path / "people.json", person_entities("Alice", "Bob"))
|
|
39
|
+
|
|
40
|
+
assert cli.main([str(data_file), "--url", db_url]) == 0
|
|
41
|
+
assert count_persons(db_url) == 2
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_seed_yaml_file(tmp_path, db_url):
|
|
45
|
+
yaml_file = tmp_path / "people.yaml"
|
|
46
|
+
yaml_file.write_text(
|
|
47
|
+
"model: tests.models.Person\ndata:\n - name: Carol\n", encoding="utf-8"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
assert cli.main([str(yaml_file), "--url", db_url]) == 0
|
|
51
|
+
assert count_persons(db_url) == 1
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def test_seed_csv_file_requires_model(tmp_path, db_url):
|
|
55
|
+
csv_file = tmp_path / "people.csv"
|
|
56
|
+
csv_file.write_text("name\nDave\nErin\n", encoding="utf-8")
|
|
57
|
+
|
|
58
|
+
exit_code = cli.main(
|
|
59
|
+
[str(csv_file), "--url", db_url, "--model", "tests.models.Person"]
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
assert exit_code == 0
|
|
63
|
+
assert count_persons(db_url) == 2
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_csv_without_model_fails(tmp_path, db_url, capsys):
|
|
67
|
+
csv_file = tmp_path / "people.csv"
|
|
68
|
+
csv_file.write_text("name\nDave\n", encoding="utf-8")
|
|
69
|
+
|
|
70
|
+
assert cli.main([str(csv_file), "--url", db_url]) == 1
|
|
71
|
+
assert "requires --model" in capsys.readouterr().err
|
|
72
|
+
assert count_persons(db_url) == 0
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_seed_directory(tmp_path, db_url):
|
|
76
|
+
seeds = tmp_path / "seeds"
|
|
77
|
+
seeds.mkdir()
|
|
78
|
+
write_json(seeds / "01_first.json", person_entities("Alice"))
|
|
79
|
+
write_json(seeds / "02_second.json", person_entities("Bob", "Carol"))
|
|
80
|
+
|
|
81
|
+
assert cli.main([str(seeds), "--url", db_url]) == 0
|
|
82
|
+
assert count_persons(db_url) == 3
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def test_multiple_paths(tmp_path, db_url):
|
|
86
|
+
first = write_json(tmp_path / "a.json", person_entities("Alice"))
|
|
87
|
+
second = write_json(tmp_path / "b.json", person_entities("Bob"))
|
|
88
|
+
|
|
89
|
+
assert cli.main([str(first), str(second), "--url", db_url]) == 0
|
|
90
|
+
assert count_persons(db_url) == 2
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def test_dry_run_rolls_back(tmp_path, db_url, capsys):
|
|
94
|
+
data_file = write_json(tmp_path / "people.json", person_entities("Alice", "Bob"))
|
|
95
|
+
|
|
96
|
+
assert cli.main([str(data_file), "--url", db_url, "--dry-run"]) == 0
|
|
97
|
+
assert "Dry run" in capsys.readouterr().out
|
|
98
|
+
assert count_persons(db_url) == 0
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def test_hybrid_seeder(tmp_path, db_url):
|
|
102
|
+
data_file = write_json(tmp_path / "people.json", person_entities("Alice"))
|
|
103
|
+
|
|
104
|
+
assert cli.main([str(data_file), "--url", db_url, "--seeder", "hybrid"]) == 0
|
|
105
|
+
assert count_persons(db_url) == 1
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def test_url_from_environment(tmp_path, db_url, monkeypatch):
|
|
109
|
+
monkeypatch.setenv("DATABASE_URL", db_url)
|
|
110
|
+
data_file = write_json(tmp_path / "people.json", person_entities("Alice"))
|
|
111
|
+
|
|
112
|
+
assert cli.main([str(data_file)]) == 0
|
|
113
|
+
assert count_persons(db_url) == 1
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def test_missing_url_errors(tmp_path, monkeypatch):
|
|
117
|
+
monkeypatch.delenv("DATABASE_URL", raising=False)
|
|
118
|
+
data_file = write_json(tmp_path / "people.json", person_entities("Alice"))
|
|
119
|
+
|
|
120
|
+
with pytest.raises(SystemExit):
|
|
121
|
+
cli.main([str(data_file)])
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def test_nonexistent_path_errors(db_url):
|
|
125
|
+
with pytest.raises(SystemExit):
|
|
126
|
+
cli.main(["does_not_exist.json", "--url", db_url])
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def test_unsupported_file_type(tmp_path, db_url):
|
|
130
|
+
bad_file = tmp_path / "people.txt"
|
|
131
|
+
bad_file.write_text("nope", encoding="utf-8")
|
|
132
|
+
|
|
133
|
+
assert cli.main([str(bad_file), "--url", db_url]) == 1
|
sqlalchemyseed-2.0.0/README.md
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
# sqlalchemyseed
|
|
2
|
-
|
|
3
|
-
[](https://pypi.org/project/sqlalchemyseed)
|
|
4
|
-
[](https://pypi.org/project/sqlalchemyseed)
|
|
5
|
-
[](https://github.com/jedymatt/sqlalchemyseed/blob/main/LICENSE)
|
|
6
|
-
[](https://github.com/jedymatt/sqlalchemyseed/actions/workflows/python-package.yml)
|
|
7
|
-
[](https://codeclimate.com/github/jedymatt/sqlalchemyseed/maintainability)
|
|
8
|
-
[](https://codecov.io/gh/jedymatt/sqlalchemyseed)
|
|
9
|
-
[](https://sqlalchemyseed.readthedocs.io/en/latest/?badge=latest)
|
|
10
|
-
|
|
11
|
-
Sqlalchemy seeder that supports nested relationships.
|
|
12
|
-
|
|
13
|
-
Supported file types
|
|
14
|
-
|
|
15
|
-
- json
|
|
16
|
-
- yaml
|
|
17
|
-
- csv
|
|
18
|
-
|
|
19
|
-
## Installation
|
|
20
|
-
|
|
21
|
-
Default installation
|
|
22
|
-
|
|
23
|
-
```shell
|
|
24
|
-
pip install sqlalchemyseed
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Quickstart
|
|
28
|
-
|
|
29
|
-
main.py
|
|
30
|
-
|
|
31
|
-
```python
|
|
32
|
-
from sqlalchemyseed import load_entities_from_json
|
|
33
|
-
from sqlalchemyseed import Seeder
|
|
34
|
-
from db import session
|
|
35
|
-
|
|
36
|
-
# load entities
|
|
37
|
-
entities = load_entities_from_json('data.json')
|
|
38
|
-
|
|
39
|
-
# Initializing Seeder
|
|
40
|
-
seeder = Seeder(session)
|
|
41
|
-
|
|
42
|
-
# Seeding
|
|
43
|
-
seeder.seed(entities)
|
|
44
|
-
|
|
45
|
-
# Committing
|
|
46
|
-
session.commit() # or seeder.session.commit()
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
data.json
|
|
50
|
-
|
|
51
|
-
```json
|
|
52
|
-
{
|
|
53
|
-
"model": "models.Person",
|
|
54
|
-
"data": [
|
|
55
|
-
{
|
|
56
|
-
"name": "John March",
|
|
57
|
-
"age": 23
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
"name": "Juan Dela Cruz",
|
|
61
|
-
"age": 21
|
|
62
|
-
}
|
|
63
|
-
]
|
|
64
|
-
}
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## Documentation
|
|
68
|
-
|
|
69
|
-
<https://sqlalchemyseed.readthedocs.io/>
|
|
70
|
-
|
|
71
|
-
## Found Bug?
|
|
72
|
-
|
|
73
|
-
Report here in this link:
|
|
74
|
-
<https://github.com/jedymatt/sqlalchemyseed/issues>
|
|
75
|
-
|
|
76
|
-
## Want to contribute?
|
|
77
|
-
|
|
78
|
-
First, Clone this [repository](https://github.com/jedymatt/sqlalchemyseed).
|
|
79
|
-
|
|
80
|
-
### Install dev dependencies
|
|
81
|
-
|
|
82
|
-
Inside the folder, paste this in the terminal to install necessary dependencies:
|
|
83
|
-
|
|
84
|
-
```shell
|
|
85
|
-
pip install -r requirements.txt -r docs/requirements.txt
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Note: make sure you have the virtual environment and enabled, or if you are using vs code and docker then you can simply re-open this as container.
|
|
89
|
-
|
|
90
|
-
### Run tests
|
|
91
|
-
|
|
92
|
-
Before running tests, make sure that the package is installed as editable:
|
|
93
|
-
|
|
94
|
-
```shell
|
|
95
|
-
python setup.py develop --user
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Then run the test:
|
|
99
|
-
|
|
100
|
-
```shell
|
|
101
|
-
pytest tests
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
Run test with coverage
|
|
105
|
-
|
|
106
|
-
```shell
|
|
107
|
-
coverage run -m pytest
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Autobuild documentation
|
|
111
|
-
|
|
112
|
-
```shell
|
|
113
|
-
sphinx-autobuild docs docs/_build/html
|
|
114
|
-
```
|
sqlalchemyseed-2.0.0/setup.cfg
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
[metadata]
|
|
2
|
-
name = sqlalchemyseed
|
|
3
|
-
version = attr: sqlalchemyseed.__version__
|
|
4
|
-
description = SQLAlchemy Seeder
|
|
5
|
-
long_description = file: README.md
|
|
6
|
-
long_description_content_type = text/markdown
|
|
7
|
-
url = https://github.com/jedymatt/sqlalchemyseed
|
|
8
|
-
author = Jedy Matt Tabasco
|
|
9
|
-
author_email = jedymatt@gmail.com
|
|
10
|
-
license = MIT
|
|
11
|
-
license_files =
|
|
12
|
-
LICENSE
|
|
13
|
-
classifiers =
|
|
14
|
-
License :: OSI Approved :: MIT License
|
|
15
|
-
Programming Language :: Python :: 3.7
|
|
16
|
-
Programming Language :: Python :: 3.8
|
|
17
|
-
Programming Language :: Python :: 3.9
|
|
18
|
-
Programming Language :: Python :: 3.10
|
|
19
|
-
Programming Language :: Python :: 3.11
|
|
20
|
-
project_urls =
|
|
21
|
-
Documentation = https://sqlalchemyseed.readthedocs.io/
|
|
22
|
-
Source = https://github.com/jedymatt/sqlalchemyseed
|
|
23
|
-
Tracker = https://github.com/jedymatt/sqlalchemyseed/issues
|
|
24
|
-
keywords = sqlalchemy, orm, seed, seeder, json, yaml
|
|
25
|
-
|
|
26
|
-
[options]
|
|
27
|
-
packages = find:
|
|
28
|
-
package_dir =
|
|
29
|
-
=src
|
|
30
|
-
install_requires =
|
|
31
|
-
SQLAlchemy>=2.0
|
|
32
|
-
python_requires = >=3.7
|
|
33
|
-
|
|
34
|
-
[options.packages.find]
|
|
35
|
-
where = src
|
|
36
|
-
|
|
37
|
-
[options.extras_require]
|
|
38
|
-
yaml =
|
|
39
|
-
PyYAML>=5.4
|
|
40
|
-
|
|
41
|
-
[egg_info]
|
|
42
|
-
tag_build =
|
|
43
|
-
tag_date = 0
|
|
44
|
-
|
sqlalchemyseed-2.0.0/setup.py
DELETED
|
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
|
|
File without changes
|
{sqlalchemyseed-2.0.0 → sqlalchemyseed-2.2.0}/src/sqlalchemyseed.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|