8000 SQLlite converter recipes result in TypeError · Issue #99392 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content
SQLlite converter recipes result in TypeError #99392
Closed
@naglis

Description

@naglis

The date/datetime SQLite converters in the Adapter and converter recipes produce TypeErrors as they seem to expect the value passed to be str, however as noted in the documentation, the converters are always passed a bytes object. In the convert_timestamp case, a cast to int (IIUC not float, as int is used in the adapt_datetime_epoch adapter recipe) is missing.

Below is an example based on the recipe to demonstrate the errors.

import datetime
import sqlite3
import traceback


def adapt_date_iso(val):
    """Adapt datetime.date to ISO 8601 date."""
    return val.isoformat()


def adapt_datetime_iso(val):
    """Adapt datetime.datetime to timezone-naive ISO 8601 date."""
    return val.isoformat()


def adapt_datetime_epoch(val):
    """Adapt datetime.datetime to Unix timestamp."""
    return int(val.timestamp())


def convert_date(val):
    """Convert ISO 8601 date to datetime.date object."""
    return datetime.date.fromisoformat(val)


def convert_datetime(val):
    """Convert ISO 8601 datetime to datetime.datetime object."""
    return datetime.datetime.fromisoformat(val)


def convert_timestamp(val):
    """Convert Unix epoch timestamp to datetime.datetime object."""
    return datetime.datetime.fromtimestamp(val)


con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)

d = datetime.date.today()
dt = datetime.datetime.now()

# Test `convert_date`.
sqlite3.register_adapter(datetime.date, adapt_date_iso)
sqlite3.register_converter("date", convert_date)

cur = con.execute("CREATE TABLE test_date(d date)")
cur.execute("INSERT INTO test_date(d) VALUES(?)", (d,))
try:
    cur.execute("SELECT d FROM test_date")
except Exception as e:
    traceback.print_exception(e)
else:
    print(f"Value from DB: {cur.fetchone()[0]}")

# Test `convert_datetime`.
sqlite3.register_adapter(datetime.datetime, adapt_datetime_iso)
sqlite3.register_converter("datetime", convert_datetime)

cur = con.execute("CREATE TABLE test_datetime(dt datetime)")
cur.execute("INSERT INTO test_datetime(dt) VALUES(?)", (dt,))
try:
    cur.execute("SELECT dt FROM test_datetime")
except Exception as e:
    traceback.print_exception(e)
else:
    print(f"Value from DB: {cur.fetchone()[0]}")


# Test `convert_timestamp`.
sqlite3.register_adapter(datetime.datetime, adapt_datetime_epoch)
sqlite3.register_converter("timestamp", convert_timestamp)

cur = con.execute("CREATE TABLE test_timestamp(ts timestamp)")
cur.execute("INSERT INTO test_timestamp(ts) VALUES(?)", (dt,))
try:
    cur.execute("SELECT ts FROM test_timestamp")
except Exception as e:
    traceback.print_exception(e)
else:
    print(f"Value from DB: {cur.fetchone()[0]}")

cur.close()
con.close()

Output:

Traceback (most recent call last):
  File "/tmp/sqlite_converter_recipe_test.py", line 48, in <module>
    cur.execute("SELECT d FROM test_date")
  File "/tmp/sqlite_converter_recipe_test.py", line 23, in convert_date
    return datetime.date.fromisoformat(val)
TypeError: fromisoformat: argument must be str
Traceback (most recent call last):
  File "/tmp/sqlite_converter_recipe_test.py", line 61, in <module>
    cur.execute("SELECT dt FROM test_datetime")
  File "/tmp/sqlite_converter_recipe_test.py", line 28, in convert_datetime
    return datetime.datetime.fromisoformat(val)
TypeError: fromisoformat: argument must be str
Traceback (most recent call last):
  File "/tmp/sqlite_converter_recipe_test.py", line 75, in <module>
    cur.execute("SELECT ts FROM test_timestamp")
  File "/tmp/sqlite_converter_recipe_test.py", line 33, in convert_timestamp
    return datetime.datetime.fromtimestamp(val)
TypeError: 'bytes' object cannot be interpreted as an integer

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests< 2B28 div class="Box-sc-g0xbh4-0 flpEwB">

    Issue actions

      0