コード例 #1
0
ファイル: __init__.py プロジェクト: gaf3/python-relations
    def test_source(self):

        source = unittest.mock.MagicMock()

        relations.SOURCES["a"] = source

        self.assertEqual(relations.source("a"), source)
コード例 #2
0
ファイル: migrations.py プロジェクト: gaf3/python-relations
    def load(self, name, file_name):
        """
        Load a file from a source
        """

        source = relations.source(name)

        return source.load(
            f"{self.directory}/{source.name}/{source.KIND}/{file_name}")
コード例 #3
0
    def update(self, *args, **kwargs):
        """
        update the model
        """

        if self._action not in ["update", "retrieve"]:
            raise ModelError(self, f"cannot update during {self._action}")

        return relations.source(self.SOURCE).update(self, *args, **kwargs)
コード例 #4
0
    def retrieve(self, verify=True, *args, **kwargs):
        """
        retrieve the model
        """

        if self._action != "retrieve":
            raise ModelError(self, f"cannot retrieve during {self._action}")

        return relations.source(self.SOURCE).retrieve(self, verify, *args, **kwargs)
コード例 #5
0
    def count(self, *args, **kwargs):
        """
        count the models
        """

        if self._action not in ["update", "retrieve"]:
            raise ModelError(self, f"cannot count during {self._action}")

        return relations.source(self.SOURCE).count(self, *args, **kwargs)
コード例 #6
0
ファイル: migrations.py プロジェクト: gaf3/python-relations
    def apply(self, name):
        """
        Applies source definitions and migrations based on a source name
        """

        source = relations.source(name)

        source_path = f"{self.directory}/{source.name}/{source.KIND}"

        return source.migrate(source_path)
コード例 #7
0
ファイル: migrations.py プロジェクト: gaf3/python-relations
    def list(self, name):
        """
        List out the migrations pairs for a source
        """

        source = relations.source(name)

        source_path = f"{self.directory}/{source.name}/{source.KIND}"

        return source.list(source_path)
コード例 #8
0
    def delete(self, *args, **kwargs):
        """
        delete the model
        """

        if self._action not in ["update", "retrieve"]:
            raise ModelError(self, f"cannot delete during {self._action}")

        if self._action == "retrieve" and self._mode == "one":
            self.retrieve()

        return relations.source(self.SOURCE).delete(self, *args, **kwargs)
コード例 #9
0
ファイル: migrations.py プロジェクト: gaf3/python-relations
    def convert(self, name):
        """
        Converts definitions and migrations to source definitions and migrations based on a source name
        """

        source = relations.source(name)

        source_path = f"{self.directory}/{source.name}/{source.KIND}"

        os.makedirs(source_path, exist_ok=True)

        for file_path in glob.glob(f"{self.directory}/*.json"):

            file_name = file_path.split("/")[-1]

            if file_name.startswith("definition"):
                source.definition(file_path, source_path)

            elif file_name.startswith("migration"):
                source.migration(file_path, source_path)
コード例 #10
0
    def query(self, action=None, *args, **kwargs):
        """
        get the current query for the model
        """

        if self._action == "create":
            return relations.source(self.SOURCE).create_query(self, *args, **kwargs).bind(self)

        if self._action == "retrieve" and action == "count":
            return relations.source(self.SOURCE).count_query(self, *args, **kwargs).bind(self)

        if self._action == "retrieve" and action == "titles":
            return relations.source(self.SOURCE).titles_query(self, *args, **kwargs).bind(self)

        if action == "update" or (action is None and self._action == "update"):
            return relations.source(self.SOURCE).update_query(self, *args, **kwargs).bind(self)

        if action == "delete":
            return relations.source(self.SOURCE).delete_query(self, *args, **kwargs).bind(self)

        return relations.source(self.SOURCE).retrieve_query(self, *args, **kwargs).bind(self)
コード例 #11
0
    def thy(cls, self=None):
        """
        Base identity to be known without instantiating the class
        """

        # If self wasn't sent, we're just providing a shell of an instance

        if self is None:
            self = ModelIdentity()
            self.__dict__.update(cls.__dict__)

        # Use TITLE, NAME if set, else use class name

        setattr(self, 'TITLE', cls.TITLE or cls.__name__)
        setattr(self, 'NAME', cls.NAME or cls.underscore(self.TITLE))

        # Derive all the fields

        fields = relations.Record()

        for name, attribute in cls.__dict__.items():

            if name.startswith('_') or name != name.lower():
                continue # pragma: no cover

            if attribute in [bool, int, float, str, set, list, dict]:
                field = relations.Field(attribute)
            elif callable(attribute):
                field = relations.Field(type(attribute()), default=attribute)
            elif isinstance(attribute, set):
                field = relations.Field(set, options=sorted(attribute))
            elif isinstance(attribute, tuple) and attribute and isinstance(attribute[0], str):
                field = relations.Field(set, options=list(attribute))
            elif isinstance(attribute, list):
                field = relations.Field(type(attribute[0]), default=attribute[0], options=attribute)
            elif isinstance(attribute, tuple):
                field = relations.Field(*attribute)
            elif isinstance(attribute, dict):
                field = relations.Field(**attribute)
            elif isinstance(attribute, relations.Field):
                field = attribute
            else:
                continue # pragma: no cover

            field.name = name

            fields.append(field)

        setattr(self, '_fields', fields)

        # Determine the _id field name

        if cls.ID is not None:
            setattr(self, '_id', self._field_name(cls.ID))

        # Figure out the titles

        titles = self.TITLES

        if not titles:
            titles = []
            for field in self._fields._order:
                if self._id == field.name:
                    continue
                if field.kind in (int, str):
                    titles.append(field.name)
                    if field.kind == str and field._none is None:
                        field.none = False
                if field.kind == str:
                    break

        if isinstance(titles, str):
            titles = [titles]

        self._titles = titles

        for field in self._titles:
            if field.split('__', 1)[0] not in self._fields:
                raise ModelError(self, f"cannot find field {field} from titles")

        # Figure out the list

        if self.LIST:
            self._list = self.LIST
        else:
            self._list = list(self._titles)
            if self._id and self._id not in self._list:
                self._list.insert(0, self._id)

        if isinstance(self._list, str):
            self._list = [self._list]

        # Make sure all the list checks out

        for field in self._list:
            if field.split('__', 1)[0] not in self._fields:
                raise ModelError(self, f"cannot find field {field} from list")

        # Figure out unique indexes

        unique = self.UNIQUE

        if unique is None:
            unique = self._titles
        elif not unique:
            unique = {}

        if isinstance(unique, str):
            unique = [unique]

        if isinstance(unique, list):
            unique = {
                "-".join(unique): unique
            }

        if isinstance(unique, dict):
            self._unique = unique

        # Make sure all the unique indexes check out

        for unique in self._unique:
            for field in self._unique[unique]:
                if field.split('__')[0] not in self._fields:
                    raise ModelError(self, f"cannot find field {field} from unique {unique}")

        index = self.INDEX or {}

        if isinstance(index, str):
            index = [index]

        if isinstance(index, list):
            index = {
                "-".join(index): index
            }

        if isinstance(index, dict):
            self._index = index

        # Make sure all the indexes check out

        for index in self._index:
            for field in self._index[index]:
                if field.split('__')[0] not in self._fields:
                    raise ModelError(self, f"cannot find field {field} from index {index}")

        # Make sure all inject fields reference actual fields that are lists or dicts

        for field, inject in [(field, field.inject.split('__')[0]) for field in self._fields._order if field.inject]:
            if inject not in self._fields:
                raise relations.FieldError(field, f"cannot find field {inject} from inject {field.inject}")
            if self._fields._names[inject].kind not in [list, dict]:
                raise relations.FieldError(self, f"field {inject} not list or dict from inject {field.inject}")

        # Determine default sort order (if desired)

        if self.ORDER:
            self._order = self._ordering(self.ORDER)
        elif self.ORDER is None and len(self._unique) == 1:
            self._order = self._ordering(list(self._unique.values())[0])
        else:
            self._order = []

        # Initialize relation models

        self.PARENTS = cls.PARENTS or {}
        self.CHILDREN = cls.CHILDREN or {}
        self.SISTERS = cls.SISTERS or {}
        self.BROTHERS = cls.BROTHERS or {}

        # Have the the source do whatever it needs to

        self.SOURCE = cls.SOURCE

        if relations.source(self.SOURCE) is not None:
            relations.source(self.SOURCE).init(self)

        return self
コード例 #12
0
 def define(cls, *args, **kwargs):
     """
     define the model
     """
     return relations.source(cls.SOURCE).define(cls.thy().define(), *args, **kwargs)
コード例 #13
0
ファイル: test_source.py プロジェクト: gaf3/python-relations
    def test___new__(self):

        source = relations.Source("testunit", reverse=True)

        self.assertEqual(relations.source("testunit"), source)
        self.assertTrue(source.reverse)