@ -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
|
||||
|
||||
@ -76,7 +76,7 @@ class UndefinedType: # pragma no cover
|
||||
|
||||
Undefined = UndefinedType()
|
||||
|
||||
__version__ = "0.10.14"
|
||||
__version__ = "0.10.15"
|
||||
__all__ = [
|
||||
"Integer",
|
||||
"BigInteger",
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"})
|
||||
|
||||
@ -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()
|
||||
Reference in New Issue
Block a user