Commit 97085de71ed022df486976901f05793c3c601182

Authored by Miguel Barão
1 parent 50d0cebf
Exists in master and in 1 other branch dev

initial convertion of learnapp to sqlalchemy 1.4/2

aprendizations/learnapp.py
@@ -6,7 +6,7 @@ This is the main controller of the application. @@ -6,7 +6,7 @@ This is the main controller of the application.
6 # python standard library 6 # python standard library
7 import asyncio 7 import asyncio
8 from collections import defaultdict 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 from datetime import datetime 10 from datetime import datetime
11 import logging 11 import logging
12 from random import random 12 from random import random
@@ -16,8 +16,8 @@ from typing import Any, Dict, Iterable, List, Optional, Tuple, Set, DefaultDict @@ -16,8 +16,8 @@ from typing import Any, Dict, Iterable, List, Optional, Tuple, Set, DefaultDict
16 # third party libraries 16 # third party libraries
17 import bcrypt 17 import bcrypt
18 import networkx as nx 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 # this project 22 # this project
23 from aprendizations.models import Student, Answer, Topic, StudentTopic 23 from aprendizations.models import Student, Answer, Topic, StudentTopic
@@ -57,22 +57,22 @@ class LearnApp(): @@ -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 def __init__(self, 78 def __init__(self,
@@ -369,30 +369,31 @@ class LearnApp(): @@ -369,30 +369,31 @@ class LearnApp():
369 ''' 369 '''
370 Fill db table 'Topic' with topics from the graph, if new 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 if new: 375 if new:
377 - sess.add_all(new) 376 + session.add_all(new)
  377 + session.commit()
378 logger.info('Added %d new topic(s) to the database', len(new)) 378 logger.info('Added %d new topic(s) to the database', len(new))
379 379
380 # ------------------------------------------------------------------------ 380 # ------------------------------------------------------------------------
381 def _db_setup(self, database: str) -> None: 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 logger.info('Checking database "%s":', database) 386 logger.info('Checking database "%s":', database)
385 if not exists(database): 387 if not exists(database):
386 raise LearnException('Database does not exist. ' 388 raise LearnException('Database does not exist. '
387 'Use "initdb-aprendizations" to create') 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 try: 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 except Exception as exc: 397 except Exception as exc:
397 logger.error('Database "%s" not usable!', database) 398 logger.error('Database "%s" not usable!', database)
398 raise DatabaseUnusableError() from exc 399 raise DatabaseUnusableError() from exc
aprendizations/models.py
1 1
2 -# python standard library  
3 -# from typing import Any  
4 -  
5 # third party libraries 2 # third party libraries
6 from sqlalchemy import Column, ForeignKey, Integer, Float, String 3 from sqlalchemy import Column, ForeignKey, Integer, Float, String
7 from sqlalchemy.orm import declarative_base, relationship 4 from sqlalchemy.orm import declarative_base, relationship
@@ -10,6 +7,7 @@ from sqlalchemy.orm import declarative_base, relationship @@ -10,6 +7,7 @@ from sqlalchemy.orm import declarative_base, relationship
10 # =========================================================================== 7 # ===========================================================================
11 # Declare ORM 8 # Declare ORM
12 # FIXME Any is a workaround for mypy static type checking (see https://github.com/python/mypy/issues/6372) 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 # Base: Any = declarative_base() 11 # Base: Any = declarative_base()
14 Base = declarative_base() 12 Base = declarative_base()
15 13
@@ -2,7 +2,6 @@ @@ -2,7 +2,6 @@
2 python_version = 3.9 2 python_version = 3.9
3 plugins = sqlalchemy.ext.mypy.plugin 3 plugins = sqlalchemy.ext.mypy.plugin
4 4
5 -  
6 [mypy-pygments.*] 5 [mypy-pygments.*]
7 ignore_missing_imports = True 6 ignore_missing_imports = True
8 7