这个周末,我一直在为Python使用sqlite3 stdlib模块。我对SQL完全陌生。
我试图编写一个测试外键的测试,但是
不幸的是segments
表似乎没有被填充,即fetchall()
不返回任何结果。我看了看db文件,每个表的声明都存在,但是似乎只填充了points
。谁能提供一些见识?
import json
import attr
import random
import pytest
import datetime as dt
import typing as typ
import sqlite3 as sql
@attr.s
class Point:
x: float = attr.ib(default=random.random())
y: float = attr.ib(default=random.random())
def adapt_point(point: Point) -> str:
data = attr.asdict(point)
text = json.dumps(data)
return text
def convert_point(value: bytes) -> Point:
data = json.loads(value)
value = Point(**data)
return value
sql.register_adapter(Point, adapt_point)
sql.register_converter('point', convert_point)
@pytest.fixture
def connection():
con = sql.connect('tmpdb.sqlite', detect_types=sql.PARSE_DECLTYPES)
cur = con.cursor()
cur.execute(
"""
create table points(
id integer primary key,
pt point,
at timestamp
);
"""
)
cur.execute(
"""
create table segments(
id integer primary key,
start integer,
end integer,
at timestamp,
foreign key(start) references points(id),
foreign key(end) references points(id)
);
"""
)
con.commit()
yield con
con.close()
def test_insert_points(connection: sql.Connection):
"""
Test adding:
* datetime object using builtin 'timestamp' adapter and converter
* dataclass object using custom adapter and converter using :py:func:`attr.asdict`
:param connection: sqlite fixture
"""
cur = connection.cursor()
for i in range(5):
cur.execute(
"insert into points(id, pt, at) values (?, ?, ?)",
(i, Point(), dt.datetime.now())
)
connection.commit()
def test_insert_segments(connection: sql.Connection):
"""
Test adding:
* datetime object using builtin 'timestamp' adapter and converter
* foreign keys to other table
:param connection: sqlite fixture
"""
cur = connection.cursor()
for i in range(3):
cur.execute(
"insert into segments(id, start, end, at) values (?, ?, ?, ?)",
(i, random.randrange(5), random.randrange(5), dt.datetime.now())
)
connection.commit()
def test_retrieve_points_from_segment(connection: sql.Connection):
cur = connection.cursor()
cur.row_factory = sql.Row
cur.execute("select * from segments")
segs = cur.fetchall()
assert segs is not None, "THIS FAILS"