Exemplo n.º 1
0
    def test_target_column(self):
        """
        Make sure the target_column is correctly set in the Pydantic schema.
        """
        class Manager(Table):
            name = Varchar(unique=True)

        class BandA(Table):
            manager = ForeignKey(Manager, target_column=Manager.name)

        class BandB(Table):
            manager = ForeignKey(Manager, target_column="name")

        class BandC(Table):
            manager = ForeignKey(Manager)

        self.assertEqual(
            create_pydantic_model(table=BandA).schema()["properties"]
            ["manager"]["extra"]["target_column"],
            "name",
        )

        self.assertEqual(
            create_pydantic_model(table=BandB).schema()["properties"]
            ["manager"]["extra"]["target_column"],
            "name",
        )

        self.assertEqual(
            create_pydantic_model(table=BandC).schema()["properties"]
            ["manager"]["extra"]["target_column"],
            "id",
        )
Exemplo n.º 2
0
    def test_invalid_column_different_table_same_type(self):
        class Computer(Table):
            CPU = Varchar()
            GPU = Varchar()

        class Computer2(Table):
            CPU = Varchar()

        with self.assertRaises(ValueError):
            create_pydantic_model(Computer, exclude_columns=(Computer2.CPU, ))
Exemplo n.º 3
0
    def test_invalid_column_str(self):
        class Computer(Table):
            CPU = Varchar()
            GPU = Varchar()

        with self.assertRaises(ValueError):
            create_pydantic_model(
                Computer,
                exclude_columns=("CPU", ),
            )
Exemplo n.º 4
0
    def test_numeric_without_digits(self):
        class Movie(Table):
            box_office = Numeric()

        try:
            create_pydantic_model(table=Movie)
        except TypeError:
            self.fail("Creating numeric field without"
                      " digits failed in pydantic model.")
        else:
            self.assertTrue(True)
Exemplo n.º 5
0
    def test_include_exclude_error(self):
        """
        An exception should be raised if both `include_columns` and
        `exclude_columns` are provided.
        """
        class Band(Table):
            name = Varchar()
            popularity = Integer()

        with self.assertRaises(ValueError):
            create_pydantic_model(
                Band,
                exclude_columns=(Band.name, ),
                include_columns=(Band.name, ),
            )
Exemplo n.º 6
0
    def test_true(self):
        """
        Make sure all foreign key columns are converted to nested models, when
        `nested=True`.
        """
        class Country(Table):
            name = Varchar(length=10)

        class Manager(Table):
            name = Varchar(length=10)
            country = ForeignKey(Country)

        class Band(Table):
            name = Varchar(length=10)
            manager = ForeignKey(Manager)

        BandModel = create_pydantic_model(table=Band, nested=True)

        #######################################################################

        ManagerModel = BandModel.__fields__["manager"].type_
        self.assertTrue(issubclass(ManagerModel, pydantic.BaseModel))
        self.assertEqual([i for i in ManagerModel.__fields__.keys()],
                         ["name", "country"])

        #######################################################################

        CountryModel = ManagerModel.__fields__["country"].type_
        self.assertTrue(issubclass(CountryModel, pydantic.BaseModel))
        self.assertEqual([i for i in CountryModel.__fields__.keys()], ["name"])
Exemplo n.º 7
0
def create_pydantic_fixture_model(fixture_configs: t.List[FixtureConfig]):
    """
    Returns a nested Pydantic model for serialising and deserialising fixtures.
    """
    columns: t.Dict[str, t.Any] = {}

    finder = Finder()

    for fixture_config in fixture_configs:

        app_columns: t.Dict[str, t.Any] = {}

        for table_class_name in fixture_config.table_class_names:
            table_class: t.Type[Table] = finder.get_table_with_name(
                app_name=fixture_config.app_name,
                table_class_name=table_class_name,
            )
            app_columns[table_class_name] = (
                t.List[  # type: ignore
                    create_pydantic_model(table_class,
                                          include_default_columns=True)],
                ...,
            )

        app_model: t.Any = pydantic.create_model(
            f"{fixture_config.app_name.title()}Model", **app_columns)

        columns[fixture_config.app_name] = (app_model, ...)

    model: t.Type[pydantic.BaseModel] = pydantic.create_model(
        "FixtureModel", **columns)

    return model
Exemplo n.º 8
0
    def test_nested(self):
        """
        Make sure that columns on related tables work.
        """
        class Manager(Table):
            name = Varchar()
            phone_number = Integer()

        class Band(Table):
            name = Varchar()
            manager = ForeignKey(Manager)
            popularity = Integer()

        pydantic_model = create_pydantic_model(
            table=Band,
            include_columns=(
                Band.name,
                Band.manager.name,
            ),
            nested=(Band.manager, ),
        )

        model_instance = pydantic_model(name="Pythonistas",
                                        manager={"name": "Guido"})
        self.assertEqual(
            model_instance.dict(),
            {
                "name": "Pythonistas",
                "manager": {
                    "name": "Guido"
                }
            },
        )
Exemplo n.º 9
0
    def test_cascaded_args(self):
        """
        Make sure that arguments passed to ``create_pydantic_model`` are
        cascaded to nested models.
        """
        class Country(Table):
            name = Varchar(length=10)

        class Manager(Table):
            name = Varchar(length=10)
            country = ForeignKey(Country)

        class Band(Table):
            name = Varchar(length=10)
            manager = ForeignKey(Manager)

        BandModel = create_pydantic_model(table=Band,
                                          nested=True,
                                          include_default_columns=True)

        ManagerModel = BandModel.__fields__["manager"].type_
        self.assertTrue(issubclass(ManagerModel, pydantic.BaseModel))
        self.assertEqual(
            [i for i in ManagerModel.__fields__.keys()],
            ["id", "name", "country"],
        )

        CountryModel = ManagerModel.__fields__["country"].type_
        self.assertTrue(issubclass(CountryModel, pydantic.BaseModel))
        self.assertEqual([i for i in CountryModel.__fields__.keys()],
                         ["id", "name"])
Exemplo n.º 10
0
    def test_text_format(self):
        class Band(Table):
            bio = Text()

        pydantic_model = create_pydantic_model(table=Band)

        self.assertEqual(
            pydantic_model.schema()["properties"]["bio"]["format"],
            "text-area",
        )
Exemplo n.º 11
0
    def test_secret_param(self):
        class TopSecret(Table):
            confidential = Secret()

        pydantic_model = create_pydantic_model(table=TopSecret)
        self.assertEqual(
            pydantic_model.schema()["properties"]["confidential"]["extra"]
            ["secret"],
            True,
        )
Exemplo n.º 12
0
    def test_array_param(self):
        class Band(Table):
            members = Array(base_column=Varchar(length=16))

        pydantic_model = create_pydantic_model(table=Band)

        self.assertEqual(
            pydantic_model.schema()["properties"]["members"]["items"]["type"],
            "string",
        )
Exemplo n.º 13
0
    def test_schema_extra_kwargs(self):
        """
        Make sure that the ``schema_extra_kwargs`` arguments are reflected in
        Pydantic model's schema.
        """
        class Band(Table):
            name = Varchar()

        model = create_pydantic_model(Band, visible_columns=("name", ))
        self.assertEqual(model.schema()["visible_columns"], ("name", ))
Exemplo n.º 14
0
    def test_all(self):
        class Computer(Table):
            CPU = Varchar()
            GPU = Varchar()

        pydantic_model = create_pydantic_model(Computer, exclude_columns=())

        properties = pydantic_model.schema()["properties"]
        self.assertIsInstance(properties["GPU"], dict)
        self.assertIsInstance(properties["CPU"], dict)
Exemplo n.º 15
0
    def test_json_format(self):
        class Movie(Table):
            features = JSON()

        pydantic_model = create_pydantic_model(table=Movie)

        self.assertEqual(
            pydantic_model.schema()["properties"]["features"]["format"],
            "json",
        )
Exemplo n.º 16
0
    def test_varchar_length(self):
        class Director(Table):
            name = Varchar(length=10)

        pydantic_model = create_pydantic_model(table=Director)

        with self.assertRaises(ValidationError):
            pydantic_model(name="This is a really long name")

        pydantic_model(name="short name")
Exemplo n.º 17
0
    def test_exclude_all_manually(self):
        class Computer(Table):
            GPU = Varchar()
            CPU = Varchar()

        pydantic_model = create_pydantic_model(
            Computer,
            exclude_columns=(Computer.GPU, Computer.CPU),
        )

        self.assertEqual(pydantic_model.schema()["properties"], {})
Exemplo n.º 18
0
    def test_help_text_present(self):
        help_text = "Movies which were released in cinemas."

        class Movie(Table, help_text=help_text):
            name = Varchar()

        pydantic_model = create_pydantic_model(table=Movie)
        self.assertEqual(
            pydantic_model.schema()["help_text"],
            help_text,
        )
Exemplo n.º 19
0
    def test_exclude_all_meta(self):
        class Computer(Table):
            GPU = Varchar()
            CPU = Varchar()

        pydantic_model = create_pydantic_model(
            Computer,
            exclude_columns=tuple(Computer._meta.columns),
        )

        self.assertEqual(pydantic_model.schema()["properties"], {})
Exemplo n.º 20
0
    def test_default(self):
        class Movie(Table):
            meta = JSON()
            meta_b = JSONB()

        pydantic_model = create_pydantic_model(table=Movie)

        json_string = '{"code": 12345}'

        model_instance = pydantic_model(meta=json_string, meta_b=json_string)
        self.assertEqual(model_instance.meta, json_string)
        self.assertEqual(model_instance.meta_b, json_string)
Exemplo n.º 21
0
    def test_help_text_present(self):
        help_text = "In millions of US dollars."

        class Movie(Table):
            box_office = Numeric(digits=(5, 1), help_text=help_text)

        pydantic_model = create_pydantic_model(table=Movie)
        self.assertEqual(
            pydantic_model.schema()["properties"]["box_office"]["extra"]
            ["help_text"],
            help_text,
        )
Exemplo n.º 22
0
    def test_include(self):
        class Band(Table):
            name = Varchar()
            popularity = Integer()

        pydantic_model = create_pydantic_model(
            Band,
            include_columns=(Band.name, ),
        )

        properties = pydantic_model.schema()["properties"]
        self.assertIsInstance(properties.get("name"), dict)
        self.assertIsNone(properties.get("popularity"))
Exemplo n.º 23
0
    def test_validation(self):
        class Movie(Table):
            meta = JSON()
            meta_b = JSONB()

        for deserialize_json in (True, False):
            pydantic_model = create_pydantic_model(
                table=Movie, deserialize_json=deserialize_json)

            json_string = "error"

            with self.assertRaises(pydantic.ValidationError):
                pydantic_model(meta=json_string, meta_b=json_string)
Exemplo n.º 24
0
    def test_exclude(self):
        class Computer(Table):
            CPU = Varchar()
            GPU = Varchar()

        pydantic_model = create_pydantic_model(
            Computer,
            exclude_columns=(Computer.CPU, ),
        )

        properties = pydantic_model.schema()["properties"]
        self.assertIsInstance(properties.get("GPU"), dict)
        self.assertIsNone(properties.get("CPU"))
Exemplo n.º 25
0
    def test_db_column_name(self):
        """
        Make sure that the Pydantic model has an alias if ``db_column_name``
        is specified for a column.
        """
        class Band(Table):
            name = Varchar(db_column_name="regrettable_column_name")

        BandModel = create_pydantic_model(table=Band)

        model = BandModel(regrettable_column_name="test")

        self.assertEqual(model.name, "test")
Exemplo n.º 26
0
    def test_deserialize_json(self):
        class Movie(Table):
            meta = JSON()
            meta_b = JSONB()

        pydantic_model = create_pydantic_model(table=Movie,
                                               deserialize_json=True)

        json_string = '{"code": 12345}'
        output = {"code": 12345}

        model_instance = pydantic_model(meta=json_string, meta_b=json_string)
        self.assertEqual(model_instance.meta, output)
        self.assertEqual(model_instance.meta_b, output)
Exemplo n.º 27
0
    def test_numeric_digits(self):
        class Movie(Table):
            box_office = Numeric(digits=(5, 1))

        pydantic_model = create_pydantic_model(table=Movie)

        with self.assertRaises(ValidationError):
            # This should fail as there are too much numbers after the decimal
            # point
            pydantic_model(box_office=decimal.Decimal("1.11"))

        with self.assertRaises(ValidationError):
            # This should fail as there are too much numbers in total
            pydantic_model(box_office=decimal.Decimal("11111.1"))

        pydantic_model(box_office=decimal.Decimal("1.0"))
Exemplo n.º 28
0
    def test_max(self):
        class Country(Table):
            name = Varchar()

        class Manager(Table):
            name = Varchar()
            country = ForeignKey(Country)

        class Band(Table):
            name = Varchar()
            manager = ForeignKey(Manager)
            assistant_manager = ForeignKey(Manager)

        class Venue(Table):
            name = Varchar()

        class Concert(Table):
            band = ForeignKey(Band)
            venue = ForeignKey(Venue)

        ConcertModel = create_pydantic_model(table=Concert,
                                             nested=True,
                                             max_recursion_depth=2)

        VenueModel = ConcertModel.__fields__["venue"].type_
        self.assertTrue(issubclass(VenueModel, pydantic.BaseModel))

        BandModel = ConcertModel.__fields__["band"].type_
        self.assertTrue(issubclass(BandModel, pydantic.BaseModel))

        ManagerModel = BandModel.__fields__["manager"].type_
        self.assertTrue(issubclass(ManagerModel, pydantic.BaseModel))

        # We should have hit the recursion depth:
        CountryModel = ManagerModel.__fields__["country"].type_
        self.assertIs(CountryModel, int)
Exemplo n.º 29
0
    def test_tuple(self):
        """
        Make sure only the specified foreign key columns are converted to
        nested models.
        """
        class Country(Table):
            name = Varchar()

        class Manager(Table):
            name = Varchar()
            country = ForeignKey(Country)

        class Band(Table):
            name = Varchar()
            manager = ForeignKey(Manager)
            assistant_manager = ForeignKey(Manager)

        class Venue(Table):
            name = Varchar()

        class Concert(Table):
            band_1 = ForeignKey(Band)
            band_2 = ForeignKey(Band)
            venue = ForeignKey(Venue)

        #######################################################################
        # Test one level deep

        BandModel = create_pydantic_model(table=Band, nested=(Band.manager, ))

        ManagerModel = BandModel.__fields__["manager"].type_
        self.assertTrue(issubclass(ManagerModel, pydantic.BaseModel))
        self.assertEqual([i for i in ManagerModel.__fields__.keys()],
                         ["name", "country"])
        self.assertEqual(ManagerModel.__qualname__, "Band.manager")

        AssistantManagerType = BandModel.__fields__["assistant_manager"].type_
        self.assertIs(AssistantManagerType, int)

        #######################################################################
        # Test two levels deep

        BandModel = create_pydantic_model(table=Band,
                                          nested=(Band.manager.country, ))

        ManagerModel = BandModel.__fields__["manager"].type_
        self.assertTrue(issubclass(ManagerModel, pydantic.BaseModel))
        self.assertEqual([i for i in ManagerModel.__fields__.keys()],
                         ["name", "country"])
        self.assertEqual(ManagerModel.__qualname__, "Band.manager")

        AssistantManagerType = BandModel.__fields__["assistant_manager"].type_
        self.assertIs(AssistantManagerType, int)

        CountryModel = ManagerModel.__fields__["country"].type_
        self.assertTrue(issubclass(CountryModel, pydantic.BaseModel))
        self.assertEqual([i for i in CountryModel.__fields__.keys()], ["name"])
        self.assertEqual(CountryModel.__qualname__, "Band.manager.country")

        #######################################################################
        # Test three levels deep

        ConcertModel = create_pydantic_model(Concert,
                                             nested=(Concert.band_1.manager, ))

        VenueModel = ConcertModel.__fields__["venue"].type_
        self.assertIs(VenueModel, int)

        BandModel = ConcertModel.__fields__["band_1"].type_
        self.assertTrue(issubclass(BandModel, pydantic.BaseModel))
        self.assertEqual(
            [i for i in BandModel.__fields__.keys()],
            ["name", "manager", "assistant_manager"],
        )
        self.assertEqual(BandModel.__qualname__, "Concert.band_1")

        ManagerModel = BandModel.__fields__["manager"].type_
        self.assertTrue(issubclass(ManagerModel, pydantic.BaseModel))
        self.assertEqual(
            [i for i in ManagerModel.__fields__.keys()],
            ["name", "country"],
        )
        self.assertEqual(ManagerModel.__qualname__, "Concert.band_1.manager")

        AssistantManagerType = BandModel.__fields__["assistant_manager"].type_
        self.assertIs(AssistantManagerType, int)

        CountryModel = ManagerModel.__fields__["country"].type_
        self.assertIs(CountryModel, int)

        #######################################################################
        # Test with `model_name` arg

        MyConcertModel = create_pydantic_model(
            Concert,
            nested=(Concert.band_1.manager, ),
            model_name="MyConcertModel",
        )

        BandModel = MyConcertModel.__fields__["band_1"].type_
        self.assertEqual(BandModel.__qualname__, "MyConcertModel.band_1")

        ManagerModel = BandModel.__fields__["manager"].type_
        self.assertEqual(ManagerModel.__qualname__,
                         "MyConcertModel.band_1.manager")