diff --git a/piccolo/utils/pydantic.py b/piccolo/utils/pydantic.py index 794406f17..57cb7de47 100644 --- a/piccolo/utils/pydantic.py +++ b/piccolo/utils/pydantic.py @@ -267,7 +267,7 @@ def create_pydantic_model( params: dict[str, Any] = {} if is_optional: - params["default"] = None + params["default"] = column.get_default_value() if column._meta.db_column_name != column._meta.name: params["alias"] = column._meta.db_column_name diff --git a/tests/apps/fixtures/commands/test_dump_load.py b/tests/apps/fixtures/commands/test_dump_load.py index 728f2f5c0..89ddc3dd1 100644 --- a/tests/apps/fixtures/commands/test_dump_load.py +++ b/tests/apps/fixtures/commands/test_dump_load.py @@ -1,5 +1,6 @@ import datetime import decimal +import json import os import tempfile import uuid @@ -10,6 +11,7 @@ dump_to_json_string, ) from piccolo.apps.fixtures.commands.load import load, load_json_string +from piccolo.apps.fixtures.commands.shared import create_pydantic_fixture_model from piccolo.utils.sync import run_sync from tests.base import engines_only from tests.example_apps.mega.tables import MegaTable, SmallTable @@ -124,6 +126,7 @@ def _run_comparison(self, table_class_names: list[str]): "json_col": '{"a":1}', "jsonb_col": '{"a":1}', "numeric_col": decimal.Decimal("1.1"), + "null_with_default_col": "Default value", "real_col": 1.1, "double_precision_col": 1.344, "smallint_col": 1, @@ -226,6 +229,7 @@ def test_dump_load_cockroach(self): "json_col": '{"a":1}', "jsonb_col": '{"a":1}', "numeric_col": decimal.Decimal("1.1"), + "null_with_default_col": "Default value", "real_col": 1.1, "double_precision_col": 1.344, "smallint_col": 1, @@ -242,6 +246,85 @@ def test_dump_load_cockroach(self): }, ) + def test_load_with_defaults(self): + """ + Make sure we can load JSON fixtures into the database, without + providing columns with default values. + """ + # We need to clear the data out now, otherwise when loading the data + # back in, there will be constraint errors over clashing primary + # keys. + MegaTable.delete(force=True).run_sync() + + pydantic_model = create_pydantic_fixture_model( + fixture_configs=[ + FixtureConfig( + app_name="mega", + table_class_names=["SmallTable", "MegaTable"], + ) + ] + ) + + run_sync( + load_json_string( + pydantic_model( + **{ + "mega": { + "SmallTable": [{"id": 1, "varchar_col": "Test"}], + "MegaTable": [ + { + "id": 1, + "bigint_col": 1, + "boolean_col": True, + "bytea_col": "hello".encode("utf8"), + "date_col": datetime.date( + year=2021, month=1, day=1 + ), + "foreignkey_col": 1, + "integer_col": 1, + "interval_col": datetime.timedelta( + seconds=10 + ), + "json_col": json.dumps({"a": 1}), + "jsonb_col": json.dumps({"a": 1}).encode( + "utf8" + ), + "numeric_col": decimal.Decimal("1.1"), + "real_col": 1.1, + "double_precision_col": 1.344, + "smallint_col": 1, + "text_col": "hello", + "timestamp_col": datetime.datetime( + year=2021, month=1, day=1 + ), + "timestamptz_col": datetime.datetime( + year=2021, + month=1, + day=1, + tzinfo=datetime.timezone.utc, + ), + "uuid_col": uuid.UUID( + "12783854-c012-4c15-8183-8eecb46f2c4e" + ), + "varchar_col": "hello", + "unique_col": "hello", + "null_col": None, + "not_null_col": "hello", + } + ], + } + }, + ).model_dump_json(indent=4) + ) + ) + + mega_table_data = MegaTable.select().run_sync() + + self.assertTrue(len(mega_table_data) == 1) + self.assertTrue( + mega_table_data[0]["null_with_default_col"] == "Default value" + ) + class TestOnConflict(TestCase): def setUp(self) -> None: diff --git a/tests/example_apps/mega/piccolo_migrations/2021-09-20T21-23-25-698988.py b/tests/example_apps/mega/piccolo_migrations/2021-09-20T21-23-25-698988.py index f204dbb7c..225f2a118 100644 --- a/tests/example_apps/mega/piccolo_migrations/2021-09-20T21-23-25-698988.py +++ b/tests/example_apps/mega/piccolo_migrations/2021-09-20T21-23-25-698988.py @@ -429,6 +429,28 @@ async def forwards(): }, ) + manager.add_column( + table_class_name="MegaTable", + tablename="mega_table", + column_name="null_with_default_col", + db_column_name="null_with_default_col", + column_class_name="Varchar", + column_class=Varchar, + params={ + "length": 255, + "default": "Default value", + "null": True, + "primary_key": False, + "unique": False, + "index": False, + "index_method": IndexMethod.btree, + "choices": None, + "db_column_name": None, + "secret": False, + }, + schema=None, + ) + manager.add_column( table_class_name="SmallTable", tablename="small_table", diff --git a/tests/example_apps/mega/tables.py b/tests/example_apps/mega/tables.py index 8947bb3e2..931ca884c 100644 --- a/tests/example_apps/mega/tables.py +++ b/tests/example_apps/mega/tables.py @@ -61,6 +61,7 @@ class MegaTable(Table): # type: ignore unique_col = Varchar(unique=True) null_col = Varchar(null=True) not_null_col = Varchar(null=False) + null_with_default_col = Varchar(null=True, default="Default value") else: @@ -92,3 +93,4 @@ class MegaTable(Table): # type: ignore unique_col = Varchar(unique=True) null_col = Varchar(null=True) not_null_col = Varchar(null=False) + null_with_default_col = Varchar(null=True, default="Default value")