Cleaned up session management.

This commit is contained in:
Alexis Lahouze 2013-12-03 23:01:17 +01:00
parent b19bb5fc7a
commit a300db9845
4 changed files with 119 additions and 178 deletions

View File

@ -15,7 +15,7 @@
along with Accountant. If not, see <http://www.gnu.org/licenses/>. along with Accountant. If not, see <http://www.gnu.org/licenses/>.
""" """
from .. import api from .. import api
from ..model import db from ..model import db, session_scope
from ..model.accounts import Account from ..model.accounts import Account
from ..model.entries import Entry from ..model.entries import Entry
from ..model.operations import Operation from ..model.operations import Operation
@ -27,116 +27,95 @@ def get_accounts():
""" """
Returns accounts with their solds. Returns accounts with their solds.
""" """
session = db.session with session_scope() as session:
query = session.query(
Account.id.label("id"),
Account.name.label("name"),
Account.authorized_overdraft.label("authorized_overdraft"),
func.sum(Entry.value).label("future"),
func.sum(case([(Entry.pointed, Entry.value,)], else_=cast(0, db.Numeric(15, 2)))).label("pointed"),
func.sum(case([(Entry.operation_date < func.now(), Entry.value,)], else_=cast(0, db.Numeric(15, 2)))).label("current")
).outerjoin(Entry).group_by(Account.id).order_by(Account.id)
query = session.query( return json.dumps([{
Account.id.label("id"), "id": i.id,
Account.name.label("name"), "name": i.name,
Account.authorized_overdraft.label("authorized_overdraft"), "authorized_overdraft": i.authorized_overdraft,
func.sum(Entry.value).label("future"), "current": str(i.current),
func.sum(case([(Entry.pointed, Entry.value,)], else_=cast(0, db.Numeric(15, 2)))).label("pointed"), "pointed": str(i.pointed),
func.sum(case([(Entry.operation_date < func.now(), Entry.value,)], else_=cast(0, db.Numeric(15, 2)))).label("current") "future": str(i.future)
).outerjoin(Entry).group_by(Account.id).order_by(Account.id) } for i in query.all()])
return json.dumps([{
"id": i.id,
"name": i.name,
"authorized_overdraft": i.authorized_overdraft,
"current": str(i.current),
"pointed": str(i.pointed),
"future": str(i.future)
} for i in query.all()])
@api.route("/accounts/<account_id>/<year>/<month>/") @api.route("/accounts/<account_id>/<year>/<month>/")
def get_account_status(account_id, year, month): def get_account_status(account_id, year, month):
session = db.session with session_scope() as session:
query = session.query(
func.sum(case([(func.sign(Operation.value) == -1, Operation.value)], else_=0)).label("expenses"),
func.sum(case([(func.sign(Operation.value) == 1, Operation.value)], else_=0)).label("revenues"),
func.sum(Operation.value).label("balance")
).filter(
Operation.account_id == account_id
).filter(
func.date_trunc('month', Operation.operation_date) == "%s-%s-01" % (year, month)
).group_by(Operation.account_id)
query = session.query( if query.count() == 1:
func.sum(case([(func.sign(Operation.value) == -1, Operation.value)], else_=0)).label("expenses"), result = query.one()
func.sum(case([(func.sign(Operation.value) == 1, Operation.value)], else_=0)).label("revenues"), revenues = result.revenues
func.sum(Operation.value).label("balance") expenses = result.expenses
).filter( balance = result.balance
Operation.account_id == account_id else:
).filter( revenues = 0.0
func.date_trunc('month', Operation.operation_date) == "%s-%s-01" % (year, month) expenses = 0.0
).group_by(Operation.account_id) balance = 0.0
if query.count() == 1: return json.dumps({
result = query.one() "expenses": str(expenses),
revenues = result.revenues "revenues": str(revenues),
expenses = result.expenses "balance": str(balance)
balance = result.balance })
else:
revenues = 0.0
expenses = 0.0
balance = 0.0
return json.dumps({
"expenses": str(expenses),
"revenues": str(revenues),
"balance": str(balance)
})
@api.route("/accounts/<account_id>/months") @api.route("/accounts/<account_id>/months")
def get_months(account_id): def get_months(account_id):
session = db.session with session_scope() as session:
query = session.query(
distinct(func.lpad(cast(extract("year", Entry.operation_date), db.String), 4, '0')).label("year"),
func.lpad(cast(extract("month", Entry.operation_date), db.String), 2, '0').label("month")
).filter(Entry.account_id == account_id).order_by("year", "month")
query = session.query( return json.dumps([{
distinct(func.lpad(cast(extract("year", Entry.operation_date), db.String), 4, '0')).label("year"), "year": i.year,
func.lpad(cast(extract("month", Entry.operation_date), db.String), 2, '0').label("month") "month": i.month.rjust(2, '0')
).filter(Entry.account_id == account_id).order_by("year", "month") } for i in query.all()])
return json.dumps([{
"year": i.year,
"month": i.month.rjust(2, '0')
} for i in query.all()])
@api.route("/accounts", methods=["PUT"]) @api.route("/accounts", methods=["PUT"])
def add_account(): def add_account():
session = db.session with session_scope() as session:
try:
account = Account(request.json['name'], request.json['authorized_overdraft']) account = Account(request.json['name'], request.json['authorized_overdraft'])
session.add(account) session.add(account)
session.commit()
return json.dumps("Account added.") return json.dumps("Account added.")
except:
session.rollback()
raise
@api.route("/accounts/<account_id>", methods=["PUT"]) @api.route("/accounts/<account_id>", methods=["PUT"])
def update_account(account_id): def update_account(account_id):
session = db.session with session_scope() as session:
try:
account = session.query(Account).filter(Account.id == account_id).first() account = session.query(Account).filter(Account.id == account_id).first()
account.name = request.json['name'] account.name = request.json['name']
account.authorized_overdraft = request.json['authorized_overdraft'] account.authorized_overdraft = request.json['authorized_overdraft']
session.merge(account) session.merge(account)
session.commit()
return json.dumps("Account #%s updated." % account_id) return json.dumps("Account #%s updated." % account_id)
except:
session.rollback()
raise
@api.route("/accounts/<account_id>", methods=["DELETE"]) @api.route("/accounts/<account_id>", methods=["DELETE"])
def delete_account(account_id): def delete_account(account_id):
session = db.session with session_scope() as session:
try:
account = session.query(Account).filter(Account.id == account_id).first() account = session.query(Account).filter(Account.id == account_id).first()
session.delete(account) session.delete(account)
session.commit()
return json.dumps("Account #%s deleted." % account_id) return json.dumps("Account #%s deleted." % account_id)
except:
session.rollback()
raise

View File

@ -15,7 +15,7 @@
along with Accountant. If not, see <http://www.gnu.org/licenses/>. along with Accountant. If not, see <http://www.gnu.org/licenses/>.
""" """
from .. import api from .. import api
from ..model import db from ..model import db, session_scope
from ..model.entries import Entry from ..model.entries import Entry
from ..model.operations import Operation from ..model.operations import Operation
from ..model.scheduled_operations import ScheduledOperation from ..model.scheduled_operations import ScheduledOperation
@ -30,37 +30,34 @@ def get_entries(account_id, year, month):
""" """
Return entries for an account, year, and month. Return entries for an account, year, and month.
""" """
session = db.session with session_scope() as session:
base_query = session.query(
Operation,
case(whens={Operation.canceled: None}, else_=func.sum(Operation.value).over(partition_by="canceled", order_by="operation_date, value desc, label desc")).label("sold")
).filter(Operation.account_id == account_id).order_by(
desc(Operation.operation_date),
Operation.value,
Operation.label,
).subquery()
base_query = session.query( query = session.query(base_query).select_from(base_query).filter(func.date_trunc('month', base_query.c.operation_date) == "%s-%s-01" % (year, month))
Operation,
case(whens={Operation.canceled: None}, else_=func.sum(Operation.value).over(partition_by="canceled", order_by="operation_date, value desc, label desc")).label("sold")
).filter(Operation.account_id == account_id).order_by(
desc(Operation.operation_date),
Operation.value,
Operation.label,
).subquery()
query = session.query(base_query).select_from(base_query).filter(func.date_trunc('month', base_query.c.operation_date) == "%s-%s-01" % (year, month)) return json.dumps([{
"id": i.id,
return json.dumps([{ "pointed": i.pointed,
"id": i.id, "operation_date": i.operation_date.strftime("%Y-%m-%d"),
"pointed": i.pointed, "label": i.label,
"operation_date": i.operation_date.strftime("%Y-%m-%d"), "value": str(i.value),
"label": i.label, "category": i.category,
"value": str(i.value), "sold": str(i.sold) if not i.canceled else None,
"category": i.category, "account_id": i.account_id,
"sold": str(i.sold) if not i.canceled else None, "canceled": i.canceled,
"account_id": i.account_id, "scheduled_operation_id": i.scheduled_operation_id
"canceled": i.canceled, } for i in query.all()])
"scheduled_operation_id": i.scheduled_operation_id
} for i in query.all()])
@api.route("/entries", methods=["PUT"]) @api.route("/entries", methods=["PUT"])
def add_entry(): def add_entry():
session = db.session with session_scope() as session:
try:
entry = Entry( entry = Entry(
operation_date = request.json['operation_date'], operation_date = request.json['operation_date'],
pointed = request.json['pointed'], pointed = request.json['pointed'],
@ -72,18 +69,12 @@ def add_entry():
) )
session.add(entry) session.add(entry)
session.commit()
return json.dumps("Entry added.") return json.dumps("Entry added.")
except:
session.rollback()
raise
@api.route("/entries/<entry_id>", methods=["PUT"]) @api.route("/entries/<entry_id>", methods=["PUT"])
def update_entry(entry_id): def update_entry(entry_id):
session = db.session with session_scope() as session:
try:
entry = session.query(Entry).filter(Entry.id == entry_id).first() entry = session.query(Entry).filter(Entry.id == entry_id).first()
entry.id = entry_id entry.id = entry_id
@ -96,25 +87,15 @@ def update_entry(entry_id):
entry.scheduled_operation_id = request.json['scheduled_operation_id'] entry.scheduled_operation_id = request.json['scheduled_operation_id']
session.merge(entry) session.merge(entry)
session.commit()
return json.dumps("Entry #%s updated." % entry_id) return json.dumps("Entry #%s updated." % entry_id)
except:
session.rollback()
raise
@api.route("/entries/<entry_id>", methods=["DELETE"]) @api.route("/entries/<entry_id>", methods=["DELETE"])
def delete_entry(entry_id): def delete_entry(entry_id):
session = db.session with session_scope() as session:
try:
entry = session.query(Entry).filter(Entry.id == entry_id).first() entry = session.query(Entry).filter(Entry.id == entry_id).first()
session.delete(entry) session.delete(entry)
session.commit()
return json.dumps("Entry #%s deleted." % entry_id) return json.dumps("Entry #%s deleted." % entry_id)
except:
session.rollback()
raise

View File

@ -1,5 +1,5 @@
from .. import api from .. import api
from ..model import db from ..model import db, session_scope
from ..model.scheduled_operations import ScheduledOperation from ..model.scheduled_operations import ScheduledOperation
from flask import json, request from flask import json, request
from sqlalchemy import func, desc from sqlalchemy import func, desc
@ -12,37 +12,34 @@ def get_scheduled_operations(account_id):
""" """
Return entries for an account, year, and month. Return entries for an account, year, and month.
""" """
session = db.session with session_scope() as session:
query = session.query(
ScheduledOperation
).select_from(
session.query(ScheduledOperation)
.filter(ScheduledOperation.account_id == account_id)
.order_by(
desc(ScheduledOperation.day),
ScheduledOperation.value,
ScheduledOperation.label,
).subquery()
)
query = session.query( return json.dumps([{
ScheduledOperation "id": i.id,
).select_from( "start_date": i.start_date.strftime("%Y-%m-%d"),
session.query(ScheduledOperation) "stop_date": i.stop_date.strftime("%Y-%m-%d"),
.filter(ScheduledOperation.account_id == account_id) "day": str(i.day),
.order_by( "frequency": str(i.frequency),
desc(ScheduledOperation.day), "label": i.label,
ScheduledOperation.value, "value": str(i.value),
ScheduledOperation.label, "category": i.category,
).subquery() "account_id": i.account_id
) } for i in query.all()])
return json.dumps([{
"id": i.id,
"start_date": i.start_date.strftime("%Y-%m-%d"),
"stop_date": i.stop_date.strftime("%Y-%m-%d"),
"day": str(i.day),
"frequency": str(i.frequency),
"label": i.label,
"value": str(i.value),
"category": i.category,
"account_id": i.account_id
} for i in query.all()])
@api.route("/scheduled_operations", methods=["PUT"]) @api.route("/scheduled_operations", methods=["PUT"])
def add_scheduled_operation(): def add_scheduled_operation():
session = db.session with session_scope() as session:
try:
scheduledOperation = ScheduledOperation( scheduledOperation = ScheduledOperation(
start_date = request.json['start_date'], start_date = request.json['start_date'],
stop_date = request.json['stop_date'], stop_date = request.json['stop_date'],
@ -55,18 +52,12 @@ def add_scheduled_operation():
) )
session.add(scheduledOperation) session.add(scheduledOperation)
session.commit()
return json.dumps("Scheduled operation added.") return json.dumps("Scheduled operation added.")
except:
session.rollback()
raise
@api.route("/scheduled_operations/<scheduled_operation_id>", methods=["PUT"]) @api.route("/scheduled_operations/<scheduled_operation_id>", methods=["PUT"])
def update_scheduled_operation(scheduled_operation_id): def update_scheduled_operation(scheduled_operation_id):
session = db.session with session_scope() as session:
try:
scheduledOperation = session.query(ScheduledOperation).filter(ScheduledOperation.id == scheduled_operation_id).first() scheduledOperation = session.query(ScheduledOperation).filter(ScheduledOperation.id == scheduled_operation_id).first()
scheduledOperation.id = scheduled_operation_id scheduledOperation.id = scheduled_operation_id
@ -80,25 +71,15 @@ def update_scheduled_operation(scheduled_operation_id):
scheduledOperation.account_id = request.json['account_id'] scheduledOperation.account_id = request.json['account_id']
session.merge(scheduledOperation) session.merge(scheduledOperation)
session.commit()
return json.dumps("Scheduled operation #%s updated." % scheduled_operation_id) return json.dumps("Scheduled operation #%s updated." % scheduled_operation_id)
except:
session.rollback()
raise
@api.route("/scheduled_operations/<scheduled_operation_id>", methods=["DELETE"]) @api.route("/scheduled_operations/<scheduled_operation_id>", methods=["DELETE"])
def delete_scheduled_operation(scheduled_operation_id): def delete_scheduled_operation(scheduled_operation_id):
session = db.session with session_scope() as session:
try:
scheduledOperation = session.query(ScheduledOperation).filter(ScheduledOperation.id == scheduled_operation_id).first() scheduledOperation = session.query(ScheduledOperation).filter(ScheduledOperation.id == scheduled_operation_id).first()
session.delete(scheduledOperation) session.delete(scheduledOperation)
session.commit()
return json.dumps("Scheduled operation #%s deleted." % scheduled_operation_id) return json.dumps("Scheduled operation #%s deleted." % scheduled_operation_id)
except:
session.rollback()
raise

View File

@ -6,19 +6,19 @@ from sqlalchemy.orm import scoped_session, sessionmaker
db = SQLAlchemy() db = SQLAlchemy()
@contextmanager @contextmanager
def session_scope(engine): def session_scope():
if engine: #session = scoped_session(sessionmaker(autocommit = False, autoflush = False, bind = engine))
session = scoped_session(sessionmaker(autocommit = False, autoflush = False, bind = engine)) session = db.session
#Base.query = session.query_property() #Base.query = session.query_property()
try: try:
yield session yield session
session.commit() session.commit()
except: except:
session.rollback() session.rollback()
raise raise
finally: finally:
session.close() session.close()
import pkgutil import pkgutil