Commit 97085de71ed022df486976901f05793c3c601182
1 parent
50d0cebf
Exists in
master
and in
1 other branch
initial convertion of learnapp to sqlalchemy 1.4/2
Showing
3 changed files
with
33 additions
and
35 deletions
Show diff stats
aprendizations/learnapp.py
| ... | ... | @@ -6,7 +6,7 @@ This is the main controller of the application. |
| 6 | 6 | # python standard library |
| 7 | 7 | import asyncio |
| 8 | 8 | from collections import defaultdict |
| 9 | -from contextlib import contextmanager # `with` statement in db sessions | |
| 9 | +# from contextlib import contextmanager # `with` statement in db sessions | |
| 10 | 10 | from datetime import datetime |
| 11 | 11 | import logging |
| 12 | 12 | from random import random |
| ... | ... | @@ -16,8 +16,8 @@ from typing import Any, Dict, Iterable, List, Optional, Tuple, Set, DefaultDict |
| 16 | 16 | # third party libraries |
| 17 | 17 | import bcrypt |
| 18 | 18 | import networkx as nx |
| 19 | -import sqlalchemy as sa | |
| 20 | -import sqlalchemy.orm as orm | |
| 19 | +from sqlalchemy import create_engine, select | |
| 20 | +from sqlalchemy.orm import Session | |
| 21 | 21 | |
| 22 | 22 | # this project |
| 23 | 23 | from aprendizations.models import Student, Answer, Topic, StudentTopic |
| ... | ... | @@ -57,22 +57,22 @@ class LearnApp(): |
| 57 | 57 | |
| 58 | 58 | |
| 59 | 59 | # ------------------------------------------------------------------------ |
| 60 | - @contextmanager | |
| 61 | - def _db_session(self, **kw): | |
| 62 | - ''' | |
| 63 | - helper to manage db sessions using the `with` statement, for example | |
| 64 | - with self._db_session() as s: s.query(...) | |
| 65 | - ''' | |
| 66 | - session = self.Session(**kw) | |
| 67 | - try: | |
| 68 | - yield session | |
| 69 | - session.commit() | |
| 70 | - except Exception: | |
| 71 | - logger.error('!!! Database rollback !!!') | |
| 72 | - session.rollback() | |
| 73 | - raise | |
| 74 | - finally: | |
| 75 | - session.close() | |
| 60 | + # @contextmanager | |
| 61 | + # def _db_session(self, **kw): | |
| 62 | + # ''' | |
| 63 | + # helper to manage db sessions using the `with` statement, for example | |
| 64 | + # with self._db_session() as s: s.query(...) | |
| 65 | + # ''' | |
| 66 | + # session = self.Session(**kw) | |
| 67 | + # try: | |
| 68 | + # yield session | |
| 69 | + # session.commit() | |
| 70 | + # except Exception: | |
| 71 | + # logger.error('!!! Database rollback !!!') | |
| 72 | + # session.rollback() | |
| 73 | + # raise | |
| 74 | + # finally: | |
| 75 | + # session.close() | |
| 76 | 76 | |
| 77 | 77 | # ------------------------------------------------------------------------ |
| 78 | 78 | def __init__(self, |
| ... | ... | @@ -369,30 +369,31 @@ class LearnApp(): |
| 369 | 369 | ''' |
| 370 | 370 | Fill db table 'Topic' with topics from the graph, if new |
| 371 | 371 | ''' |
| 372 | - with self._db_session() as sess: | |
| 373 | - new = [Topic(id=t) for t in topics | |
| 374 | - if (t,) not in sess.query(Topic.id)] | |
| 375 | - | |
| 372 | + with Session(self._engine) as session: | |
| 373 | + db_topics = session.execute(select(Topic.id)).scalars().all() | |
| 374 | + new = [Topic(id=t) for t in topics if t not in db_topics] | |
| 376 | 375 | if new: |
| 377 | - sess.add_all(new) | |
| 376 | + session.add_all(new) | |
| 377 | + session.commit() | |
| 378 | 378 | logger.info('Added %d new topic(s) to the database', len(new)) |
| 379 | 379 | |
| 380 | 380 | # ------------------------------------------------------------------------ |
| 381 | 381 | def _db_setup(self, database: str) -> None: |
| 382 | - '''setup and check database contents''' | |
| 382 | + ''' | |
| 383 | + Setup and check database contents | |
| 384 | + ''' | |
| 383 | 385 | |
| 384 | 386 | logger.info('Checking database "%s":', database) |
| 385 | 387 | if not exists(database): |
| 386 | 388 | raise LearnException('Database does not exist. ' |
| 387 | 389 | 'Use "initdb-aprendizations" to create') |
| 388 | 390 | |
| 389 | - engine = sa.create_engine(f'sqlite:///{database}', echo=False) | |
| 390 | - self.Session = orm.sessionmaker(bind=engine) | |
| 391 | + self._engine = create_engine(f'sqlite:///{database}', future=True) | |
| 391 | 392 | try: |
| 392 | - with self._db_session() as sess: | |
| 393 | - count_students: int = sess.query(Student).count() | |
| 394 | - count_topics: int = sess.query(Topic).count() | |
| 395 | - count_answers: int = sess.query(Answer).count() | |
| 393 | + with Session(self._engine) as session: | |
| 394 | + count_students: int = session.query(Student).count() | |
| 395 | + count_topics: int = session.query(Topic).count() | |
| 396 | + count_answers: int = session.query(Answer).count() | |
| 396 | 397 | except Exception as exc: |
| 397 | 398 | logger.error('Database "%s" not usable!', database) |
| 398 | 399 | raise DatabaseUnusableError() from exc | ... | ... |
aprendizations/models.py
| 1 | 1 | |
| 2 | -# python standard library | |
| 3 | -# from typing import Any | |
| 4 | - | |
| 5 | 2 | # third party libraries |
| 6 | 3 | from sqlalchemy import Column, ForeignKey, Integer, Float, String |
| 7 | 4 | from sqlalchemy.orm import declarative_base, relationship |
| ... | ... | @@ -10,6 +7,7 @@ from sqlalchemy.orm import declarative_base, relationship |
| 10 | 7 | # =========================================================================== |
| 11 | 8 | # Declare ORM |
| 12 | 9 | # FIXME Any is a workaround for mypy static type checking (see https://github.com/python/mypy/issues/6372) |
| 10 | +# from typing import Any | |
| 13 | 11 | # Base: Any = declarative_base() |
| 14 | 12 | Base = declarative_base() |
| 15 | 13 | ... | ... |