Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,29 @@ Sqlalchemy seeder that supports nested relationships.

## Installation

Default installation

```commandline
pip install sqlalchemyseed
```

### Dependencies
When using yaml to loading entities from yaml files.
Execute this command to install necessary dependencies

```commandline
pip install sqlalchemyseed[yaml]
```

## Dependencies

Required

- SQAlchemy>=1.4.0

Optional

- PyYAML>=5.4.0

## Getting Started

```python
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
sqlalchemy>=1.4.0
jsonschema>=3.2.0
pyyaml>=5.4.0
14 changes: 11 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import re

from readme_renderer import markdown
from setuptools import setup

with open("README.md", "r", encoding="utf-8") as fh:
Expand All @@ -10,20 +11,27 @@
pattern = r"^__version__ = ['\"]([^'\"]*)['\"]"
VERSION = re.search(pattern, f.read(), re.MULTILINE).group(1)


extras_require = {
'yaml': ['PyYAML>=5.4.0']
}


setup(
name='sqlalchemyseed',
author='jedymatt',
url='https://github.com/jedymatt/sqlalchemyseed',
long_description=LONG_DESCRIPTION,
long_description=markdown.render(LONG_DESCRIPTION),
long_description_content_type='text/markdown',
description='SQLAlchemy seeder.',
version=VERSION,
license='MIT',
packages=['sqlalchemyseed'],
package_data={'sqlalchemyseed': ['res/*']},
# package_data={'sqlalchemyseed': ['res/*']},
install_requires=['SQLAlchemy>=1.4.0'],
extras_require=extras_require,
python_requires='>=3.6.0',
keywords='sqlalchemy seed seeder json',
keywords='sqlalchemy seed seeder json yaml',
project_urls={
'Source': 'https://github.com/jedymatt/sqlalchemyseed',
'Tracker': 'https://github.com/jedymatt/sqlalchemyseed/issues',
Expand Down
9 changes: 7 additions & 2 deletions sqlalchemyseed/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from .seeder import ClassRegistry
from .seeder import HybridSeeder
from .seeder import Seeder
from .seeder import load_entities_from_json
from .loader import load_entities_from_json
from .loader import load_entities_from_yaml

__version__ = '0.4.1'
__version__ = '0.4.2.dev1'


if __name__ == '__main__':
pass
48 changes: 48 additions & 0 deletions sqlalchemyseed/loader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import json
import sys

try:
# relative import
from . import validator
except ImportError:
import validator


try:
import yaml
except ModuleNotFoundError:
pass


def load_entities_from_json(json_filepath):
try:
with open(json_filepath, 'r') as f:
entities = json.loads(f.read())
except FileNotFoundError as error:
raise FileNotFoundError(error)

validator.SchemaValidator.validate(entities)

return entities


def load_entities_from_yaml(yaml_filepath):
if 'yaml' not in sys.modules:
raise ModuleNotFoundError(
'PyYAML is not installed and is required to run this function. '
'To use this function, py -m pip install "sqlalchemyseed[yaml]"'
)

try:
with open(yaml_filepath, 'r') as f:
entities = yaml.load(f.read(), Loader=yaml.SafeLoader)
except FileNotFoundError as error:
raise FileNotFoundError(error)

validator.SchemaValidator.validate(entities)

return entities


if __name__ == '__main__':
load_entities_from_yaml('tests/res/data.yaml')
32 changes: 11 additions & 21 deletions sqlalchemyseed/seeder.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
import importlib
import json
from inspect import isclass

import sqlalchemy.orm
from sqlalchemy import Table, column, inspect, select, table, text
from sqlalchemy import inspect
from sqlalchemy.exc import NoInspectionAvailable
from sqlalchemy.orm import ColumnProperty, RelationshipProperty
from sqlalchemy.orm.relationships import foreign

from . import validator


def load_entities_from_json(json_filepath):
try:
with open(json_filepath, 'r') as f:
entities = json.loads(f.read())
except FileNotFoundError as error:
raise FileNotFoundError(error)

validator.SchemaValidator.validate(entities)

return entities
try:
# relative import
from . import validator
except ImportError:
import validator


class ClassRegistry:
Expand Down Expand Up @@ -218,7 +208,7 @@ def instantiate_obj(self, class_path, kwargs, key_is_data, parent, parent_attr_n
class_attr = getattr(parent.__class__, parent_attr_name)
if isinstance(class_attr.property, ColumnProperty):
raise TypeError('invalid class attribute type')

obj = class_(**filtered_kwargs)
self._session.add(obj)
# self._session.flush()
Expand All @@ -229,17 +219,17 @@ def instantiate_obj(self, class_path, kwargs, key_is_data, parent, parent_attr_n
if isinstance(class_attr.property, ColumnProperty):
foreign_key = str(
list(getattr(parent.__class__, parent_attr_name).foreign_keys)[0].column)
foreign_key_id=self._query_instance_id(
foreign_key_id = self._query_instance_id(
class_, filtered_kwargs, foreign_key)
return foreign_key_id

return self._session.query(class_).filter_by(**filtered_kwargs).one()

def _query_instance_id(self, class_, filtered_kwargs, foreign_key):
# .id should be the foreign key
arr=foreign_key.rsplit('.')
column_name=arr[len(arr)-1]
arr = foreign_key.rsplit('.')
column_name = arr[len(arr)-1]

result=self.session.query(
result = self.session.query(
getattr(class_, column_name)).filter_by(**filtered_kwargs).one()
return getattr(result, column_name)
File renamed without changes.
6 changes: 6 additions & 0 deletions tests/res/data.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- model: tests.models.Employee
data:
name: Juan Dela Cruz
- model: tests.models.Company
data:
name: Carte
15 changes: 15 additions & 0 deletions tests/test_loader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import unittest

from sqlalchemyseed import load_entities_from_json, load_entities_from_yaml


class TestLoader(unittest.TestCase):
def test_load_entities_from_json(self):
entities = load_entities_from_json('tests/res/data.json')

self.assertEqual(len(entities), 6)

def test_load_entities_from_yaml(self):
entities = load_entities_from_yaml('tests/res/data.yaml')
print(entities)
self.assertEqual(len(entities), 2)