fixes for #270 and #274

This commit is contained in:
collerek
2021-07-21 14:39:23 +02:00
parent 5e0f704864
commit b423c1c56d
6 changed files with 100 additions and 19 deletions

View File

@ -1,3 +1,12 @@
# 0.10.15
## 🐛 Fixes
* Fix generating pydantic models tree with nested models (by @pawamoy - thanks!) [#278](https://github.com/collerek/ormar/issues/278)
* Fix missing f-string in warning about missing primary key field [#274](https://github.com/collerek/ormar/issues/274)
* Fix passing foreign key value as relation (additional guard, fixed already in the latest release) [#270](https://github.com/collerek/ormar/issues/270)
# 0.10.14
## ✨ Features

View File

@ -76,7 +76,7 @@ class UndefinedType: # pragma no cover
Undefined = UndefinedType()
__version__ = "0.10.14"
__version__ = "0.10.15"
__all__ = [
"Integer",
"BigInteger",

View File

@ -152,7 +152,7 @@ def sqlalchemy_columns_from_model_fields(
if len(model_fields.keys()) == 0:
model_fields["id"] = ormar.Integer(name="id", primary_key=True)
logging.warning(
"Table {table_name} had no fields so auto "
f"Table {new_model.Meta.tablename} had no fields so auto "
"Integer primary key named `id` created."
)
validate_related_names_in_relations(model_fields, new_model)

View File

@ -121,7 +121,7 @@ class SavePrepareMixin(RelationMixin, AliasMixin):
f"model without pk set!"
)
model_dict[field] = pk_value
elif field_value: # nested dict
elif isinstance(field_value, (list, dict)) and field_value:
if isinstance(field_value, list):
model_dict[field] = [
target.get(target_pkname) for target in field_value

View File

@ -26,8 +26,7 @@ class Package(ormar.Model):
pass
id: int = ormar.Integer(primary_key=True)
library: Library = ormar.ForeignKey(Library,
related_name="packages")
library: Library = ormar.ForeignKey(Library, related_name="packages")
version: str = ormar.String(max_length=100)
@ -47,34 +46,26 @@ class TicketPackage(ormar.Model):
id: int = ormar.Integer(primary_key=True)
status: str = ormar.String(max_length=100)
ticket: Ticket = ormar.ForeignKey(Ticket, related_name="packages")
package: Package = ormar.ForeignKey(Package,
related_name="tickets")
package: Package = ormar.ForeignKey(Package, related_name="tickets")
def test_have_proper_children():
TicketPackageOut = TicketPackage.get_pydantic(exclude={"ticket"})
assert 'package' in TicketPackageOut.__fields__
assert "package" in TicketPackageOut.__fields__
PydanticPackage = TicketPackageOut.__fields__["package"].type_
assert 'library' in PydanticPackage.__fields__
assert "library" in PydanticPackage.__fields__
def test_casts_properly():
payload = {
"id": 0,
"status": "string",
"ticket": {
"id": 0,
"number": 0,
"status": "string"
},
"ticket": {"id": 0, "number": 0, "status": "string"},
"package": {
"version": "string",
"id": 0,
"library": {
"id": 0,
"name": "string"
}
}
"library": {"id": 0, "name": "string"},
},
}
test_package = TicketPackage(**payload)
TicketPackageOut = TicketPackage.get_pydantic(exclude={"ticket"})

View File

@ -0,0 +1,81 @@
import uuid
from typing import List, Optional
import databases
import pytest
import sqlalchemy
import ormar
from tests.settings import DATABASE_URL
database = databases.Database(DATABASE_URL, force_rollback=True)
metadata = sqlalchemy.MetaData()
class BaseMeta(ormar.ModelMeta):
metadata = metadata
database = database
class PageLink(ormar.Model):
class Meta(BaseMeta):
tablename = "pagelinks"
id: int = ormar.Integer(primary_key=True)
value: str = ormar.String(max_length=2048)
country: str = ormar.String(max_length=1000)
class Post(ormar.Model):
class Meta(BaseMeta):
tablename = "posts"
id: int = ormar.Integer(primary_key=True)
title: str = ormar.String(max_length=500)
link: PageLink = ormar.ForeignKey(
PageLink, related_name="posts", ondelete="CASCADE"
)
class Department(ormar.Model):
class Meta(BaseMeta):
pass
id: uuid.UUID = ormar.UUID(primary_key=True, default=uuid.uuid4())
name: str = ormar.String(max_length=100)
class Course(ormar.Model):
class Meta(BaseMeta):
pass
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
department: Optional[Department] = ormar.ForeignKey(Department)
@pytest.fixture(autouse=True, scope="module")
def create_test_database():
engine = sqlalchemy.create_engine(DATABASE_URL)
metadata.create_all(engine)
yield
metadata.drop_all(engine)
@pytest.mark.asyncio
async def test_pass_int_values_as_fk():
async with database:
async with database.transaction(force_rollback=True):
link = await PageLink(id=1, value="test", country="USA").save()
await Post.objects.create(title="My post", link=link.id)
post_check = await Post.objects.select_related("link").get()
assert post_check.link == link
@pytest.mark.asyncio
async def test_pass_uuid_value_as_fk():
async with database:
async with database.transaction(force_rollback=True):
dept = await Department(name="Department test").save()
await Course(name="Test course", department=dept.id).save()