@ -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
|
# 0.10.14
|
||||||
|
|
||||||
## ✨ Features
|
## ✨ Features
|
||||||
|
|||||||
@ -76,7 +76,7 @@ class UndefinedType: # pragma no cover
|
|||||||
|
|
||||||
Undefined = UndefinedType()
|
Undefined = UndefinedType()
|
||||||
|
|
||||||
__version__ = "0.10.14"
|
__version__ = "0.10.15"
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"Integer",
|
"Integer",
|
||||||
"BigInteger",
|
"BigInteger",
|
||||||
|
|||||||
@ -152,7 +152,7 @@ def sqlalchemy_columns_from_model_fields(
|
|||||||
if len(model_fields.keys()) == 0:
|
if len(model_fields.keys()) == 0:
|
||||||
model_fields["id"] = ormar.Integer(name="id", primary_key=True)
|
model_fields["id"] = ormar.Integer(name="id", primary_key=True)
|
||||||
logging.warning(
|
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."
|
"Integer primary key named `id` created."
|
||||||
)
|
)
|
||||||
validate_related_names_in_relations(model_fields, new_model)
|
validate_related_names_in_relations(model_fields, new_model)
|
||||||
|
|||||||
@ -121,7 +121,7 @@ class SavePrepareMixin(RelationMixin, AliasMixin):
|
|||||||
f"model without pk set!"
|
f"model without pk set!"
|
||||||
)
|
)
|
||||||
model_dict[field] = pk_value
|
model_dict[field] = pk_value
|
||||||
elif field_value: # nested dict
|
elif isinstance(field_value, (list, dict)) and field_value:
|
||||||
if isinstance(field_value, list):
|
if isinstance(field_value, list):
|
||||||
model_dict[field] = [
|
model_dict[field] = [
|
||||||
target.get(target_pkname) for target in field_value
|
target.get(target_pkname) for target in field_value
|
||||||
|
|||||||
@ -26,8 +26,7 @@ class Package(ormar.Model):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
id: int = ormar.Integer(primary_key=True)
|
id: int = ormar.Integer(primary_key=True)
|
||||||
library: Library = ormar.ForeignKey(Library,
|
library: Library = ormar.ForeignKey(Library, related_name="packages")
|
||||||
related_name="packages")
|
|
||||||
version: str = ormar.String(max_length=100)
|
version: str = ormar.String(max_length=100)
|
||||||
|
|
||||||
|
|
||||||
@ -47,34 +46,26 @@ class TicketPackage(ormar.Model):
|
|||||||
id: int = ormar.Integer(primary_key=True)
|
id: int = ormar.Integer(primary_key=True)
|
||||||
status: str = ormar.String(max_length=100)
|
status: str = ormar.String(max_length=100)
|
||||||
ticket: Ticket = ormar.ForeignKey(Ticket, related_name="packages")
|
ticket: Ticket = ormar.ForeignKey(Ticket, related_name="packages")
|
||||||
package: Package = ormar.ForeignKey(Package,
|
package: Package = ormar.ForeignKey(Package, related_name="tickets")
|
||||||
related_name="tickets")
|
|
||||||
|
|
||||||
|
|
||||||
def test_have_proper_children():
|
def test_have_proper_children():
|
||||||
TicketPackageOut = TicketPackage.get_pydantic(exclude={"ticket"})
|
TicketPackageOut = TicketPackage.get_pydantic(exclude={"ticket"})
|
||||||
assert 'package' in TicketPackageOut.__fields__
|
assert "package" in TicketPackageOut.__fields__
|
||||||
PydanticPackage = TicketPackageOut.__fields__["package"].type_
|
PydanticPackage = TicketPackageOut.__fields__["package"].type_
|
||||||
assert 'library' in PydanticPackage.__fields__
|
assert "library" in PydanticPackage.__fields__
|
||||||
|
|
||||||
|
|
||||||
def test_casts_properly():
|
def test_casts_properly():
|
||||||
payload = {
|
payload = {
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"status": "string",
|
"status": "string",
|
||||||
"ticket": {
|
"ticket": {"id": 0, "number": 0, "status": "string"},
|
||||||
"id": 0,
|
|
||||||
"number": 0,
|
|
||||||
"status": "string"
|
|
||||||
},
|
|
||||||
"package": {
|
"package": {
|
||||||
"version": "string",
|
"version": "string",
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"library": {
|
"library": {"id": 0, "name": "string"},
|
||||||
"id": 0,
|
},
|
||||||
"name": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
test_package = TicketPackage(**payload)
|
test_package = TicketPackage(**payload)
|
||||||
TicketPackageOut = TicketPackage.get_pydantic(exclude={"ticket"})
|
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