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

View File

@ -7,9 +7,17 @@ import psycopg2
import psycopg2.extras import psycopg2.extras
def database_connection(): class DatabaseManager():
connection = psycopg2.connect("dbname={} user={} password={} host={} port={}".format(DATABASE_NAME, DATABASE_USER, DATABASE_PASS, DATABASE_HOST, DATABASE_PORT), cursor_factory=psycopg2.extras.DictCursor) '''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: # vim: set sw=4 ts=4 expandtab:

View File

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