Skip to content
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
3 changes: 3 additions & 0 deletions asynch/proto/columns/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ def prepare_items(self, items):
async def write_data(self, items):
if self.nullable:
await self._write_nulls_map(items)
else:
if None in items:
raise ColumnTypeMismatchException(None)

await self._write_data(items)

Expand Down
21 changes: 21 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,26 @@ async def initialize_tests():
ORDER BY id
"""
)
await cursor.execute(
"""
CREATE TABLE if not exists test.asynch_nullable
(
`id` Int32,
`cnt` Nullable(Int32),
`decimal` Nullable(Decimal(10, 2)),
`date` Nullable(Date),
`datetime` Nullable(DateTime),
`float` Nullable(Float32),
`uuid` Nullable(UUID),
`string` Nullable(String),
`ipv4` Nullable(IPv4),
`ipv6` Nullable(IPv6),
`bool` Nullable(Bool)
)
ENGINE = MergeTree
ORDER BY id
"""
)
yield


Expand All @@ -96,6 +116,7 @@ async def truncate_table():
async with Connection(dsn=CONNECTION_DSN) as conn:
async with conn.cursor(cursor=DictCursor) as cursor:
await cursor.execute("truncate table test.asynch")
await cursor.execute("truncate table test.asynch_nullable")
yield


Expand Down
77 changes: 77 additions & 0 deletions tests/test_cursors.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from asynch.connection import Connection
from asynch.cursors import DictCursor
from asynch.errors import TypeMismatchError
from asynch.proto import constants


Expand Down Expand Up @@ -114,6 +115,82 @@ async def test_insert_dict(conn: Connection):
assert rows == 1


@pytest.mark.asyncio
async def test_nullable_insert_dict(conn: Connection):
async with conn.cursor(cursor=DictCursor) as cursor:
rows = await cursor.execute(
"""INSERT INTO test.asynch_nullable("""
"""id,cnt,decimal,date,datetime,float,uuid,string,ipv4,ipv6,bool) VALUES""",
[
{
"id": 1,
"cnt": None,
"decimal": None,
"date": None,
"datetime": None,
"float": None,
"uuid": None,
"string": None,
"ipv4": None,
"ipv6": None,
"bool": None,
}
],
)
assert rows == 1

await cursor.execute("SELECT * FROM test.asynch_nullable")
result = await cursor.fetchone()
del result["id"]
assert len([item for item in result.values() if item is not None]) == 0


@pytest.mark.asyncio
async def test_nullable_in_non_nullable_insert_dict(conn: Connection):
async with conn.cursor(cursor=DictCursor) as cursor:
try:
await cursor.execute(
"""INSERT INTO test.asynch(id,string) VALUES""",
[
{
"id": 1,
"string": None,
}
],
)
assert False
except TypeMismatchError:
assert True

try:
await cursor.execute(
"""INSERT INTO test.asynch(id,decimal) VALUES""",
[
{
"id": 1,
"decimal": None,
}
],
)
assert False
except TypeMismatchError:
assert True

try:
await cursor.execute(
"""INSERT INTO test.asynch(id,float) VALUES""",
[
{
"id": 1,
"float": None,
}
],
)
assert False
except TypeMismatchError:
assert True


@pytest.mark.asyncio
async def test_insert_tuple(conn: Connection):
async with conn.cursor(cursor=DictCursor) as cursor:
Expand Down
Loading