Skip to content

Commit

Permalink
Merge pull request #36 from jedymatt/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
jedymatt authored May 27, 2022
2 parents 3ad5253 + cebfcac commit e77d7f5
Show file tree
Hide file tree
Showing 29 changed files with 1,128 additions and 291 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
python -m pip install flake8 pytest
pip install -r requirements.txt
# install local
pip install -e .[dev]
pip install -e .
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,9 @@ Then run the test:
```shell
pytest tests
```

Run test with coverage

```shell
coverage run -m pytest
```
Empty file added docs/source/_static/.gitkeep
Empty file.
30 changes: 14 additions & 16 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,32 @@ API Reference
Seeders
-------

.. autoclass:: sqlalchemyseed.Seeder
:members:
:undoc-members:

.. autoclass:: sqlalchemyseed.HybridSeeder
.. automodule:: sqlalchemyseed.seeder
:members:
:undoc-members:

Loaders
-------

.. autofunction:: sqlalchemyseed.load_entities_from_json

.. autofunction:: sqlalchemyseed.load_entities_from_yaml

.. autofunction:: sqlalchemyseed.load_entities_from_csv

.. automodule:: sqlalchemyseed.loader
:members:

Validators
----------

.. autofunction:: sqlalchemyseed.validator.validate

.. autofunction:: sqlalchemyseed.validator.hybrid_validate

.. automodule:: sqlalchemyseed.validator
:members:
:undoc-members:

Exceptions
----------

.. automodule:: sqlalchemyseed.errors
:members:
:members:

Utilities
---------

.. automodule:: sqlalchemyseed.util
:members:
:undoc-members:
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
SQLAlchemy>=1.4
dataclasses>=0.8; python_version == "3.6"
# dataclasses>=0.8; python_version == "3.6"
PyYAML>=5.4
coverage>=6.2
tox
pytest
pylint
autopep8
4 changes: 2 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ package_dir =
=src
install_requires =
SQLAlchemy>=1.4
dataclasses>=0.8; python_version == "3.6"
; dataclasses>=0.8; python_version == "3.6"
python_requires = >=3.6

[options.packages.find]
Expand All @@ -38,4 +38,4 @@ where = src
[options.extras_require]
yaml =
PyYAML>=5.4


8 changes: 4 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from setuptools import setup


setup()
from setuptools import setup


setup()
2 changes: 2 additions & 0 deletions src/sqlalchemyseed/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
from .loader import load_entities_from_json
from .loader import load_entities_from_yaml
from .loader import load_entities_from_csv
from . import util
from . import attribute


__version__ = "1.0.6-dev"
Expand Down
70 changes: 70 additions & 0 deletions src/sqlalchemyseed/attribute.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""
attribute module containing helper functions for instrumented attribute.
"""

from functools import lru_cache
from inspect import isclass

from sqlalchemy.orm import ColumnProperty, RelationshipProperty
from sqlalchemy.orm.attributes import InstrumentedAttribute, get_attribute, set_attribute


def instrumented_attribute(class_or_instance, key: str):
"""
Returns instrumented attribute from the class or instance.
"""

if isclass(class_or_instance):
return getattr(class_or_instance, key)

return getattr(class_or_instance.__class__, key)


def attr_is_relationship(instrumented_attr: InstrumentedAttribute):
"""
Check if instrumented attribute property is a RelationshipProperty
"""
return isinstance(instrumented_attr.property, RelationshipProperty)


def attr_is_column(instrumented_attr: InstrumentedAttribute):
"""
Check if instrumented attribute property is a ColumnProperty
"""
return isinstance(instrumented_attr.property, ColumnProperty)


def set_instance_attribute(instance, key, value):
"""
Set attribute value of instance
"""

instr_attr: InstrumentedAttribute = getattr(instance.__class__, key)

if attr_is_relationship(instr_attr) and instr_attr.property.uselist:
get_attribute(instance, key).append(value)
else:
set_attribute(instance, key, value)

@lru_cache()
def foreign_key_column(instrumented_attr: InstrumentedAttribute):
"""
Returns the table name of the first foreignkey.
"""
return next(iter(instrumented_attr.foreign_keys)).column

@lru_cache()
def referenced_class(instrumented_attr: InstrumentedAttribute):
"""
Returns class that the attribute is referenced to.
"""

if attr_is_relationship(instrumented_attr):
return instrumented_attr.mapper.class_

table_name = foreign_key_column(instrumented_attr).table.name

return next(filter(
lambda mapper: mapper.class_.__tablename__ == table_name,
instrumented_attr.parent.registry.mappers
)).class_
4 changes: 4 additions & 0 deletions src/sqlalchemyseed/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
MODEL_KEY = 'model'
DATA_KEY = 'data'
FILTER_KEY = 'filter'
SOURCE_KEYS = [DATA_KEY, FILTER_KEY]
4 changes: 4 additions & 0 deletions src/sqlalchemyseed/dynamic_seeder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class DynamicSeeder:
"""
DynamicSeeder class
"""
15 changes: 0 additions & 15 deletions src/sqlalchemyseed/errors.py
Original file line number Diff line number Diff line change
@@ -1,53 +1,38 @@
class ClassNotFoundError(Exception):
"""Raised when the class is not found"""
pass


class MissingKeyError(Exception):
"""Raised when a required key is missing"""
pass


class MaxLengthExceededError(Exception):
"""Raised when maximum length of data exceeded"""
pass


class InvalidTypeError(Exception):
"""Raised when a type of data is not accepted"""
pass


class EmptyDataError(Exception):
"""Raised when data is empty"""
pass


class InvalidKeyError(Exception):
"""Raised when an invalid key is invoked"""
pass


class ParseError(Exception):
"""Raised when parsing string fails"""
pass


class UnsupportedClassError(Exception):
"""Raised when an unsupported class is invoked"""
pass


class NotInModuleError(Exception):
"""Raised when a value is not found in module"""
pass


class InvalidModelPath(Exception):
"""Raised when an invalid model path is invoked"""
pass


class UnsupportedClassError(Exception):
"""Raised when an unsupported class is invoked"""
pass
Loading

0 comments on commit e77d7f5

Please sign in to comment.