开发者

Is it better to change the db schema?

开发者 https://www.devze.com 2023-02-04 07:53 出处:网络
I\'m building a web app with django. I use postgresql for the db. The app code is getting really messy(my begginer skills being a big factor) and slow, even when I run the app locally.

I'm building a web app with django. I use postgresql for the db. The app code is getting really messy(my begginer skills being a big factor) and slow, even when I run the app locally.

This is an excerpt of my models.py file:

REPEATS_CHOICES = (
    (NEVER, 'Never'),
    (DAILY, 'Daily'),
    (WEEKLY, 'Weekly'),
    (MONTHLY, 'Monthly'),
    ...some more...
)

class Transaction(models.Model):
    name = models.CharField(max_length=30)
    type = models.IntegerField(max_length=1, choices=TYPE_CHOICES) # 0 = 'Income' , 1 = 'Expense'
    amount = models.DecimalField(max_digits=12, decimal_places=2)
    date = models.DateField(default=date.today)
    frequency = models.IntegerField(max_length=2, choices=REPEATS_CHOICES)
    ends = models.DateField(blank=True, null=True)
    active = models.BooleanField(default=True)
    category = models.ForeignKey(Category, related_name='transactions', blank=True, null=True)
    account = models.ForeignKey(Account, related_name='transactions')

The problem is with date, frequency and ends. With this info I can know all the dates in which transactions occurs and use it to fill a cashflow table. Doing things this way involves creating a lot of structures(dictionaries, lists and tuples) and iterating them a lot. Maybe there is a very simple way of solving this with the actual schema, but I couldn't realize how.

I think that the app would be easier to code if, at the creation of a transaction, I could save all the dates in the db. I don't know if it's possible or if it's a good idea.

I'm reading a book about google app engine and the datastore's multivalued properties. What do you think about this for solving my problem?.

Edit: I didn't know about the PickleField. I'm now reading about it, maybe I could use it to store all the transaction's datetime objects.

Edit2: This is an excerpt of my cashflow2 view(sorry for the horrible code):

def cashflow2(request, account_name="Initial"):

if account_name == "Initial":
    uri = "/cashflow/new_account"
    return HttpResponseRedirect(uri)     
month_info = {}
cat_info = {}
m_y_list = [] # [(month,year),]
trans = []
min, max = [] , []

account = Account.objects.get(name=account_name, user=request.user)
categories = account.categories.all() 
for year in range(2006,2017):
    for month in range(1,13):
        month_info[(month, year)] = [0, 0, 0]
        for cat in categories:
            cat_info[(cat, month, year)] = 0

previous_months = 1 # previous months from actual
next_months = 5
dates_list = month_year_list(previous_month, next_months) # Returns [(month,year)] from the requested range
m_y_list = [(date.month, date.year) for date in month_year_list(1,5)]
min, max = dates_list[0], dates_list[-1]
INCOME = 0
EXPENSE = 1
ONHAND = 2
transacs_in_dates = []
txs = account.transactions.order_by('date')

for tx in txs:
    monthyear = ()
    monthyear = (tx.date.month, tx.date.year)
    if tx.frequency == 0:
        if tx.type == 0:
            month_info[monthyear][INCOME] += tx.amount
            if tx.category:
                cat_info[(tx.category, monthyear[0], monthyear[1])] += tx.amount
        else:
            month_info[monthyear][EXPENSE] += tx.amount
            if tx.category:
                cat_info[(tx.category, monthyear[0], monthyear[1])] += tx.amount
        if monthyear in lista_m_a:
            if tx not in transacs_in_dates:
                transacs_in_dates.append(tx)
    elif tx.frequency == 4: # frequency = 'Monthly'
        months_dif = relativedelta.relativedelta(tx.ends, tx.date).months
        if tx.ends.day < tx.date.day:
            months_dif += 1
        years_dif = relativedelta.relativedelta(tx.ends, tx.date).years
        dif = months_dif + (years_dif*12)
        dates_range = dif + 1
        for i in range(dates_range):
            dt = tx.date+relativedelta.relativedelta(months=+i)
            if (dt.month, dt.year) in m_y_list:
                if tx not in transacs_in_dates:
    开发者_运维知识库                transacs_in_dates.append(tx)
            if tx.type == 0:
                month_info[(fch.month,fch.year)][INCOME] += tx.amount
                if tx.category:
                    cat_info[(tx.category, fch.month, fch.year)] += tx.amount
            else:
                month_info[(fch.month,fch.year)][EXPENSE] += tx.amount
                if tx.category:
                    cat_info[(tx.category, fch.month, fch.year)] += tx.amount

import operator
thelist = []
thelist = sorted((my + tuple(v) for my, v in month_info.iteritems()),
             key = operator.itemgetter(1, 0))
thelistlist = []
for atuple in thelist:
    thelistlist.append(list(atuple))
for i in range(len(thelistlist)):
    if i != 0:
        thelistlist[i][4] = thelistlist[i-1][2] - thelistlist[i-1][3] + thelistlist[i-1][4]
list = []
for el in thelistlist:
    if (el[0],el[1]) in lista_m_a:
        list.append(el)

transactions = account.transactions.all()

cats_in_dates_income = []
cats_in_dates_expense = []
for t in transacs_in_dates:
    if t.category and t.type == 0:
        if t.category not in cats_in_dates_income:
            cats_in_dates_income.append(t.category)
    elif t.category and t.type == 1:
        if t.category not in cats_in_dates_expense:
            cats_in_dates_expense.append(t.category)

cat_infos = []
for k, v in cat_info.items():
    cat_infos.append((k[0], k[1], k[2], v))


Depends on how relevant App Engine is here. P.S. If you'd like to store pickled objects as well as JSON objects in the Google Datastore, check out these two code snippets:

http://kovshenin.com/archives/app-engine-json-objects-google-datastore/ http://kovshenin.com/archives/app-engine-python-objects-in-the-google-datastore/

Also note that the Google Datastore is a non-relational database, so you might have other trouble refactoring your code to switch to that.

Cheers and good luck!

0

精彩评论

暂无评论...
验证码 换一张
取 消