Skip to content

Commit e77d7f5

Browse files
authored
Merge pull request #36 from jedymatt/dev
Dev
2 parents 3ad5253 + cebfcac commit e77d7f5

29 files changed

+1128
-291
lines changed

.github/workflows/python-package.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
python -m pip install flake8 pytest
3232
pip install -r requirements.txt
3333
# install local
34-
pip install -e .[dev]
34+
pip install -e .
3535
- name: Lint with flake8
3636
run: |
3737
# stop the build if there are Python syntax errors or undefined names

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,9 @@ Then run the test:
100100
```shell
101101
pytest tests
102102
```
103+
104+
Run test with coverage
105+
106+
```shell
107+
coverage run -m pytest
108+
```

docs/source/_static/.gitkeep

Whitespace-only changes.

docs/source/api.rst

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,32 @@ API Reference
44
Seeders
55
-------
66

7-
.. autoclass:: sqlalchemyseed.Seeder
8-
:members:
9-
:undoc-members:
10-
11-
.. autoclass:: sqlalchemyseed.HybridSeeder
7+
.. automodule:: sqlalchemyseed.seeder
128
:members:
139
:undoc-members:
1410

1511
Loaders
1612
-------
1713

18-
.. autofunction:: sqlalchemyseed.load_entities_from_json
19-
20-
.. autofunction:: sqlalchemyseed.load_entities_from_yaml
21-
22-
.. autofunction:: sqlalchemyseed.load_entities_from_csv
23-
14+
.. automodule:: sqlalchemyseed.loader
15+
:members:
2416

2517
Validators
2618
----------
2719

28-
.. autofunction:: sqlalchemyseed.validator.validate
29-
30-
.. autofunction:: sqlalchemyseed.validator.hybrid_validate
31-
20+
.. automodule:: sqlalchemyseed.validator
21+
:members:
22+
:undoc-members:
3223

3324
Exceptions
3425
----------
3526

3627
.. automodule:: sqlalchemyseed.errors
37-
:members:
28+
:members:
29+
30+
Utilities
31+
---------
32+
33+
.. automodule:: sqlalchemyseed.util
34+
:members:
35+
:undoc-members:

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
SQLAlchemy>=1.4
2-
dataclasses>=0.8; python_version == "3.6"
2+
# dataclasses>=0.8; python_version == "3.6"
33
PyYAML>=5.4
44
coverage>=6.2
5+
tox
56
pytest
67
pylint
78
autopep8

setup.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ package_dir =
2929
=src
3030
install_requires =
3131
SQLAlchemy>=1.4
32-
dataclasses>=0.8; python_version == "3.6"
32+
; dataclasses>=0.8; python_version == "3.6"
3333
python_requires = >=3.6
3434

3535
[options.packages.find]
@@ -38,4 +38,4 @@ where = src
3838
[options.extras_require]
3939
yaml =
4040
PyYAML>=5.4
41-
41+

setup.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from setuptools import setup
2-
3-
4-
setup()
1+
from setuptools import setup
2+
3+
4+
setup()

src/sqlalchemyseed/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
from .loader import load_entities_from_json
2828
from .loader import load_entities_from_yaml
2929
from .loader import load_entities_from_csv
30+
from . import util
31+
from . import attribute
3032

3133

3234
__version__ = "1.0.6-dev"

src/sqlalchemyseed/attribute.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
"""
2+
attribute module containing helper functions for instrumented attribute.
3+
"""
4+
5+
from functools import lru_cache
6+
from inspect import isclass
7+
8+
from sqlalchemy.orm import ColumnProperty, RelationshipProperty
9+
from sqlalchemy.orm.attributes import InstrumentedAttribute, get_attribute, set_attribute
10+
11+
12+
def instrumented_attribute(class_or_instance, key: str):
13+
"""
14+
Returns instrumented attribute from the class or instance.
15+
"""
16+
17+
if isclass(class_or_instance):
18+
return getattr(class_or_instance, key)
19+
20+
return getattr(class_or_instance.__class__, key)
21+
22+
23+
def attr_is_relationship(instrumented_attr: InstrumentedAttribute):
24+
"""
25+
Check if instrumented attribute property is a RelationshipProperty
26+
"""
27+
return isinstance(instrumented_attr.property, RelationshipProperty)
28+
29+
30+
def attr_is_column(instrumented_attr: InstrumentedAttribute):
31+
"""
32+
Check if instrumented attribute property is a ColumnProperty
33+
"""
34+
return isinstance(instrumented_attr.property, ColumnProperty)
35+
36+
37+
def set_instance_attribute(instance, key, value):
38+
"""
39+
Set attribute value of instance
40+
"""
41+
42+
instr_attr: InstrumentedAttribute = getattr(instance.__class__, key)
43+
44+
if attr_is_relationship(instr_attr) and instr_attr.property.uselist:
45+
get_attribute(instance, key).append(value)
46+
else:
47+
set_attribute(instance, key, value)
48+
49+
@lru_cache()
50+
def foreign_key_column(instrumented_attr: InstrumentedAttribute):
51+
"""
52+
Returns the table name of the first foreignkey.
53+
"""
54+
return next(iter(instrumented_attr.foreign_keys)).column
55+
56+
@lru_cache()
57+
def referenced_class(instrumented_attr: InstrumentedAttribute):
58+
"""
59+
Returns class that the attribute is referenced to.
60+
"""
61+
62+
if attr_is_relationship(instrumented_attr):
63+
return instrumented_attr.mapper.class_
64+
65+
table_name = foreign_key_column(instrumented_attr).table.name
66+
67+
return next(filter(
68+
lambda mapper: mapper.class_.__tablename__ == table_name,
69+
instrumented_attr.parent.registry.mappers
70+
)).class_

src/sqlalchemyseed/constants.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
MODEL_KEY = 'model'
2+
DATA_KEY = 'data'
3+
FILTER_KEY = 'filter'
4+
SOURCE_KEYS = [DATA_KEY, FILTER_KEY]

0 commit comments

Comments
 (0)