+
Skip to content

Fix pk read only: now primary key can be written as a custom value #163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
14 changes: 13 additions & 1 deletion orm/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,22 @@ def __init__(
**kwargs: typing.Any,
) -> None:
if primary_key:
kwargs["read_only"] = True
default_value = kwargs.get("default", None)
self.raise_if_pk_without_default(default_value)
kwargs['allow_null'] = True

self.allow_null = kwargs.get("allow_null", False)
self.primary_key = primary_key
self.index = index
self.unique = unique
self.validator = self.get_validator(**kwargs)

def raise_if_pk_without_default(self, default: typing.Any):
if not default:
raise ValueError(
f"You need to specify default value for {self.__class__.__name__} primary key field"
)

def get_column(self, name: str) -> sqlalchemy.Column:
column_type = self.get_column_type()
constraints = self.get_constraints()
Expand Down Expand Up @@ -70,6 +79,9 @@ def get_column_type(self):


class Integer(ModelField):
def raise_if_pk_without_default(self, default: typing.Any):
pass

def get_validator(self, **kwargs) -> typesystem.Field:
return typesystem.Integer(**kwargs)

Expand Down
6 changes: 3 additions & 3 deletions orm/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,14 +410,14 @@ def _validate_kwargs(self, **kwargs):
for key, value in fields.items():
if value.validator.read_only and value.validator.has_default():
kwargs[key] = value.validator.get_default_value()
return kwargs

return {key: value for key, value in kwargs.items() if value is not None}

async def create(self, **kwargs):
kwargs = self._validate_kwargs(**kwargs)
instance = self.model_cls(**kwargs)
expr = self.table.insert().values(**kwargs)

if self.pkname not in kwargs:
if not self.pkname in kwargs:
instance.pk = await self.database.execute(expr)
else:
await self.database.execute(expr)
Expand Down
16 changes: 16 additions & 0 deletions tests/test_columns.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ async def test_model_crud():
assert product.updated_date == last_updated_date


async def test_create_user_with_custom_uuid():
custom_uuid = uuid.uuid4()
user = await User.objects.create(id=custom_uuid)
assert user.pk == custom_uuid


async def test_both_auto_now_and_auto_now_add_raise_error():
with pytest.raises(ValueError):

Expand Down Expand Up @@ -159,3 +165,13 @@ async def test_bulk_create():
assert products[1].data == {"foo": 456}
assert products[1].value == 456.789
assert products[1].status == StatusEnum.DRAFT


async def test_create_with_pk_not_integer_and_without_default_value():
with pytest.raises(ValueError):

class Post(orm.Model):
registry = models
fields = {
"id": orm.UUID(primary_key=True)
}
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载