1
0
mirror of https://github.com/ilri/dspace-statistics-api.git synced 2024-06-29 01:23:45 +02:00

Refactor database code to use a context manager

Instead of opening one global persistent database connection when
the application I am now abstracting it to a class that I can use
in combination with Python's "with" context. Both connections and
cursors are kept for the context of each "with" block and closed
automatically when exiting.

See: https://alysivji.github.io/managing-resources-with-context-managers-pythonic.html
See: http://initd.org/psycopg/docs/connection.html#connection.close
This commit is contained in:
Alan Orth 2018-11-07 17:41:21 +02:00
parent e39f2b260c
commit 2f342be948
Signed by: alanorth
GPG Key ID: 0FB860CC9C45B1B9
3 changed files with 108 additions and 101 deletions

View File

@ -1,9 +1,6 @@
from .database import database_connection
from .database import DatabaseManager
import falcon
db = database_connection()
db.set_session(readonly=True)
class RootResource:
def on_get(self, req, resp):
@ -21,8 +18,10 @@ class AllItemsResource:
page = req.get_param_as_int("page", min=0) or 0
offset = limit * page
cursor = db.cursor()
with DatabaseManager() as db:
db.set_session(readonly=True)
with db.cursor() as cursor:
# get total number of items so we can estimate the pages
cursor.execute('SELECT COUNT(id) FROM items')
pages = round(cursor.fetchone()[0] / limit)
@ -37,8 +36,6 @@ class AllItemsResource:
for item in cursor:
statistics.append({'id': item['id'], 'views': item['views'], 'downloads': item['downloads']})
cursor.close()
message = {
'currentPage': page,
'totalPages': pages,
@ -53,6 +50,10 @@ class ItemResource:
def on_get(self, req, resp, item_id):
"""Handles GET requests"""
with DatabaseManager() as db:
db.set_session(readonly=True)
with db.cursor() as cursor:
cursor = db.cursor()
cursor.execute('SELECT views, downloads FROM items WHERE id={}'.format(item_id))
if cursor.rowcount == 0:
@ -71,8 +72,6 @@ class ItemResource:
resp.media = statistics
cursor.close()
api = application = falcon.API()
api.add_route('/', RootResource())

View File

@ -7,9 +7,17 @@ import psycopg2
import psycopg2.extras
def database_connection():
connection = psycopg2.connect("dbname={} user={} password={} host={} port={}".format(DATABASE_NAME, DATABASE_USER, DATABASE_PASS, DATABASE_HOST, DATABASE_PORT), cursor_factory=psycopg2.extras.DictCursor)
class DatabaseManager():
'''Manage database connection.'''
return connection
def __init__(self):
self._connection_uri = 'dbname={} user={} password={} host={} port={}'.format(DATABASE_NAME, DATABASE_USER, DATABASE_PASS, DATABASE_HOST, DATABASE_PORT)
def __enter__(self):
self._connection = psycopg2.connect(self._connection_uri, cursor_factory=psycopg2.extras.DictCursor)
return self._connection
def __exit__(self, exc_type, exc_value, exc_traceback):
self._connection.close()
# vim: set sw=4 ts=4 expandtab:

View File

@ -29,7 +29,7 @@
# See: https://solrclient.readthedocs.io/en/latest/SolrClient.html
# See: https://wiki.duraspace.org/display/DSPACE/Solr
from .database import database_connection
from .database import DatabaseManager
import json
import psycopg2.extras
from .solr import solr_connection
@ -63,8 +63,8 @@ def index_views():
results_num_pages = int(results_totalNumFacets / results_per_page)
results_current_page = 0
cursor = db.cursor()
with DatabaseManager() as db:
with db.cursor() as cursor:
# create an empty list to store values for batch insertion
data = []
@ -97,8 +97,6 @@ def index_views():
results_current_page += 1
cursor.close()
def index_downloads():
# get the total number of distinct facets for items with at least 1 download
@ -123,8 +121,8 @@ def index_downloads():
results_num_pages = int(results_totalNumFacets / results_per_page)
results_current_page = 0
cursor = db.cursor()
with DatabaseManager() as db:
with db.cursor() as cursor:
# create an empty list to store values for batch insertion
data = []
@ -157,19 +155,21 @@ def index_downloads():
results_current_page += 1
cursor.close()
db = database_connection()
solr = solr_connection()
print("gonna create the table")
with DatabaseManager() as db:
with db.cursor() as cursor:
# create table to store item views and downloads
cursor = db.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS items
(id INT PRIMARY KEY, views INT DEFAULT 0, downloads INT DEFAULT 0)''')
# commit the table creation before closing the database connection
db.commit()
index_views()
index_downloads()
db.close()
# vim: set sw=4 ts=4 expandtab: