From 9f32a0db0b77fe46b6e44573c3f989ee96626fb7 2013-02-25 15:28:37 From: Lance Edgar Date: 2013-02-25 15:28:37 Subject: [PATCH] Added `purge-batches` command. This command will delete forever all batches whose purge date has passed. It is meant to be run on a scheduled basis, e.g. nightly. --- diff --git a/rattail/commands.py b/rattail/commands.py index a69ced2458724866251272365d410ceb32895fdf..4039b1df3178acec75d9bbc989ec31ba1fea1554 100644 --- a/rattail/commands.py +++ b/rattail/commands.py @@ -163,7 +163,35 @@ class PalmCommand(commands.Subcommand): # Unregister conduit's COM server. from win32com.server.register import UnregisterClasses UnregisterClasses(palm.PalmConduit) + +class PurgeBatchesCommand(commands.Subcommand): + """ + .. highlight:: sh + + Purges stale batches from the database; called as:: + + rattail purge-batches + """ + + name = 'purge-batches' + description = "Purge stale batches from the database" + + def run(self, args): + from rattail.db.batches.util import purge_batches + + edbob.init_modules(['edbob.db', 'rattail.db']) + + print "Purging batches from database:" + print " %s" % edbob.engine.url + + session = edbob.Session() + purged = purge_batches(session) + session.commit() + session.close() + + print "\nPurged %d batches" % purged + def main(*args): """ diff --git a/rattail/db/batches/util.py b/rattail/db/batches/util.py new file mode 100644 index 0000000000000000000000000000000000000000..bd3344b7c0213c701fc448b7cce4ca84f5c68eb0 --- /dev/null +++ b/rattail/db/batches/util.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2012 Lance Edgar +# +# This file is part of Rattail. +# +# Rattail is free software: you can redistribute it and/or modify it under the +# terms of the GNU Affero General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for +# more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Rattail. If not, see . +# +################################################################################ + +""" +``rattail.db.batches.util`` -- Batch Utilities +""" + +import re + +from sqlalchemy import MetaData + +import edbob +from edbob.time import local_time + +import rattail +from rattail.db.extension.model import Batch + + +def purge_batches(session, effective_date=None): + """ + Purge batches from the database which are considered old. + + :param session: Active database session. + :type session: ``sqlalchemy.orm.Session`` instance + + :param effective_date: Date against which comparisons should be made when + determining if a batch is "old" (based on its + :attr:`rattail.db.model.Batch.purge` attribute). If no value is + provided, then :func:`rattail.time.local_time()` is called to determine + the current date. + :type effective_date: ``datetime.date`` instance, or ``None`` + + :returns: ``None`` + """ + + if effective_date is None: + edbob.init_modules(['edbob.time']) + effective_date = local_time().date() + + purged = 0 + + q = session.query(Batch) + q = q.filter(Batch.purge != None) + q = q.filter(Batch.purge < effective_date) + for batch in q: + batch.drop_table() + session.delete(batch) + session.flush() + purged += 1 + + # This should theoretically not be necessary, if/when the batch processing + # is cleaning up after itself properly. For now though, it seems that + # orphaned data tables are sometimes being left behind. + + batch_pattern = re.compile(r'^batch\.[0-9a-f]{32}$') + + current_batches = [] + for batch in session.query(Batch): + current_batches.append('batch.%s' % batch.uuid) + + def orphaned_batches(name, metadata): + if batch_pattern.match(name): + if name not in current_batches: + return True + return False + + metadata = MetaData(session.bind) + metadata.reflect(only=orphaned_batches) + for table in reversed(metadata.sorted_tables): + table.drop() + + return purged diff --git a/setup.py b/setup.py index e5591eb82d3637df48bd705493bab9577a74ef72..3f9d53772f2f5dfa03781ee1888175b13c11c219 100644 --- a/setup.py +++ b/setup.py @@ -116,6 +116,7 @@ dbsync = rattail.commands:DatabaseSyncCommand filemon = rattail.commands:FileMonitorCommand load-host-data = rattail.commands:LoadHostDataCommand palm = rattail.commands:PalmCommand +purge-batches = rattail.commands:PurgeBatchesCommand [rattail.batches.providers] print_labels = rattail.batches.providers.labels:PrintLabels