Change schema: just record numbers per family

This commit is contained in:
Remi Rampin 2022-05-10 20:48:51 -04:00
parent 26c86e2a0a
commit 31526f41f3
3 changed files with 52 additions and 73 deletions

View File

@ -22,78 +22,56 @@ def get_db():
db.close() db.close()
def get_people_and_replies(code): def get_name_and_replies(code):
with get_db() as db: with get_db() as db:
return list(db.execute( rows = db.execute(
'''\ '''\
WITH latest_reply AS (
SELECT
adults, children
FROM replies
WHERE family_code = :code
ORDER BY date DESC
LIMIT 1
)
SELECT SELECT
persons.id, persons.name, families.name,
( (SELECT adults FROM latest_reply) AS adults,
SELECT rsvp FROM replies (SELECT children FROM latest_reply) AS children
WHERE FROM families
replies.person_id = persons.id WHERE families.code = :code
AND replies.date = ( LIMIT 1;
SELECT MAX(date)
FROM replies
WHERE person_id = persons.id
)
) AS rsvp
FROM
persons
WHERE
persons.code = :code;
''', ''',
dict(code=code), dict(code=code),
))
def record_reply(code, persons):
assert isinstance(persons, dict)
with get_db() as db:
# Check the IDs of people match
expected_people_ids = set(
row[0]
for row in db.execute(
'''\
SELECT
id
FROM
persons
WHERE
code = :code;
''',
dict(code=code),
)
) )
if not expected_people_ids: try:
logger.warning("Got reply with invalid code %r", code) return next(rows)
except StopIteration:
raise ValueError("Invalid code") raise ValueError("Invalid code")
for person_id in persons.keys():
if person_id not in expected_people_ids:
logger.warning(
"Got invalid person id=%d for code %r",
person_id,
code,
)
raise ValueError("Invalid person")
def record_reply(code, adults, children):
assert isinstance(adults, int)
assert isinstance(children, int)
assert 0 <= adults and 0 <= children
assert adults > 0 or children == 0
with get_db() as db:
# Insert update # Insert update
cursor = db.cursor() cursor = db.cursor()
date = datetime.utcnow() date = datetime.utcnow()
for person_id, rsvp in persons.items(): cursor.execute(
if rsvp not in ('yes', 'no'): '''\
raise ValueError("Invalid rsvp %r", rsvp) INSERT INTO replies(family_code, date, adults, children)
cursor.execute( VALUES(:code, :date, :adults, :children);
'''\ ''',
INSERT INTO replies(person_id, date, rsvp) dict(code=code, date=date, adults=adults, children=children),
VALUES(:id, :date, :rsvp); )
''',
dict(id=person_id, date=date, rsvp=rsvp),
)
cursor.execute('COMMIT;') cursor.execute('COMMIT;')
logger.info( logger.info(
"Recorded update for code=%r date=%r persons: %s", "Recorded update for code=%r date=%r adults=%d children=%d",
code, code,
date, date,
' '.join('%d=%s' % p for p in sorted(persons.items())), adults,
children,
) )

View File

@ -1,11 +1,12 @@
CREATE TABLE persons( CREATE TABLE families(
id INTEGER PRIMARY KEY, code VARCHAR(8) PRIMARY KEY,
code VARCHAR(8) NOT NULL, name TEXT
name TEXT NOT NULL
); );
CREATE TABLE replies( CREATE TABLE replies(
person_id INTEGER NOT NULL, family_code VARCHAR(8) NOT NULL,
date DATETIME NOT NULL, date DATETIME NOT NULL,
rsvp VARCHAR(8) NOT NULL adults INTEGER NOT NULL,
children INTEGER NOT NULL,
FOREIGN KEY(family_code) REFERENCES families(code)
); );

View File

@ -1,9 +1,9 @@
INSERT INTO persons(id, code, name) VALUES INSERT INTO families(code, name) VALUES
(1, 'aaaa', 'one'), ('aaaa', 'one'),
(2, 'aaaa', 'two'), ('bbbb', 'two'),
(3, 'bbbb', 'three'); ('cccc', 'three');
INSERT INTO replies(person_id, date, rsvp) VALUES INSERT INTO replies(family_code, date, adults, children) VALUES
(1, '2022-05-10 20:37:39', 'yes'), ('aaaa', '2022-05-10 20:37:39', 2, 0),
(2, '2022-05-10 20:37:39', 'yes'), ('aaaa', '2022-05-10 23:55:55', 0, 0),
(1, '2022-05-10 23:55:55', 'no'); ('bbbb', '2022-05-10 20:22:11', 2, 1);