Change schema: just record numbers per family
This commit is contained in:
parent
26c86e2a0a
commit
31526f41f3
|
@ -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,
|
||||||
)
|
)
|
||||||
|
|
|
@ -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)
|
||||||
);
|
);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue