fix json nullable column
This commit is contained in:
@ -168,7 +168,7 @@ class ModelFieldFactory:
|
||||
unique=kwargs.pop("unique", False),
|
||||
pydantic_only=pydantic_only,
|
||||
autoincrement=autoincrement,
|
||||
column_type=cls.get_column_type(**kwargs),
|
||||
column_type=cls.get_column_type(**kwargs, sql_nullable=sql_nullable),
|
||||
choices=choices,
|
||||
encrypt_secret=encrypt_secret,
|
||||
encrypt_backend=encrypt_backend,
|
||||
@ -516,7 +516,7 @@ class JSON(ModelFieldFactory, pydantic.Json):
|
||||
:return: initialized column with proper options
|
||||
:rtype: sqlalchemy Column
|
||||
"""
|
||||
return sqlalchemy.JSON()
|
||||
return sqlalchemy.JSON(none_as_null=kwargs.get("sql_nullable", False))
|
||||
|
||||
|
||||
if TYPE_CHECKING: # pragma: nocover # noqa: C901
|
||||
|
||||
@ -2,7 +2,7 @@ import base64
|
||||
import datetime
|
||||
import decimal
|
||||
import uuid
|
||||
from typing import Any, Callable, Dict, Union
|
||||
from typing import Any, Callable, Dict, Optional, Union
|
||||
|
||||
import pydantic
|
||||
from pydantic.datetime_parse import parse_date, parse_datetime, parse_time
|
||||
@ -37,7 +37,7 @@ def encode_bytes(value: Union[str, bytes], represent_as_string: bool = False) ->
|
||||
return value if isinstance(value, bytes) else value.encode("utf-8")
|
||||
|
||||
|
||||
def encode_json(value: Any) -> str:
|
||||
def encode_json(value: Any) -> Optional[str]:
|
||||
value = json.dumps(value) if not isinstance(value, str) else re_dump_value(value)
|
||||
value = value.decode("utf-8") if isinstance(value, bytes) else value
|
||||
return value
|
||||
|
||||
@ -22,14 +22,11 @@ from typing import (
|
||||
import databases
|
||||
import pydantic
|
||||
import sqlalchemy
|
||||
|
||||
from ormar.fields.parsers import encode_json
|
||||
from ormar.models.utils import Extra
|
||||
from pydantic import BaseModel
|
||||
|
||||
try:
|
||||
import orjson as json
|
||||
except ImportError: # pragma: no cover
|
||||
import json # type: ignore
|
||||
|
||||
|
||||
import ormar # noqa I100
|
||||
from ormar.exceptions import ModelError, ModelPersistenceError
|
||||
@ -925,12 +922,7 @@ class NewBaseModel(pydantic.BaseModel, ModelTableProxy, metaclass=ModelMetaclass
|
||||
"""
|
||||
if column_name not in self._json_fields:
|
||||
return value
|
||||
if not isinstance(value, str):
|
||||
try:
|
||||
value = json.dumps(value)
|
||||
except TypeError: # pragma no cover
|
||||
pass
|
||||
return value.decode("utf-8") if isinstance(value, bytes) else value
|
||||
return encode_json(value)
|
||||
|
||||
def _extract_own_model_fields(self) -> Dict:
|
||||
"""
|
||||
|
||||
@ -34,6 +34,18 @@ class Book(ormar.Model):
|
||||
year: int = ormar.Integer(nullable=True)
|
||||
|
||||
|
||||
class JsonModel(ormar.Model):
|
||||
class Meta(ormar.ModelMeta):
|
||||
metadata = metadata
|
||||
database = database
|
||||
tablename = "jsons"
|
||||
|
||||
id = ormar.Integer(primary_key=True)
|
||||
text_field = ormar.Text(nullable=True)
|
||||
json_field = ormar.JSON(nullable=True)
|
||||
json_not_null = ormar.JSON()
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True, scope="module")
|
||||
def create_test_database():
|
||||
engine = sqlalchemy.create_engine(DATABASE_URL)
|
||||
@ -83,3 +95,16 @@ async def test_is_null():
|
||||
assert len(tolkien.books) == 2
|
||||
assert tolkien.books[0].year == 1955
|
||||
assert tolkien.books[0].title == "The Lord of the Rings"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_isnull_json():
|
||||
async with database:
|
||||
author = await JsonModel.objects.create(json_not_null=None)
|
||||
assert author.json_field is None
|
||||
non_null_text_fields = await JsonModel.objects.all(text_field__isnull=False)
|
||||
assert len(non_null_text_fields) == 0
|
||||
non_null_json_fields = await JsonModel.objects.all(json_field__isnull=False)
|
||||
assert len(non_null_json_fields) == 0
|
||||
non_null_json_fields = await JsonModel.objects.all(json_not_null__isnull=False)
|
||||
assert len(non_null_json_fields) == 1
|
||||
|
||||
Reference in New Issue
Block a user