简体   繁体   中英

using python 2.7 function to query sqlite3 DB

I'm making a program where people, by giving their info (education, field of study, higher degree achieved etc.) are given a score. I'm using sqlite3 and Python 2.7

To do so, I have a DB in which each city and province is listed with the percentage of people education's highest degree. I have made one table for each province:

DB:

table: province_1

cities| no certificate| high school diploma| Apprenticeship| bachelor| etc..
city1 :     5         |        15          |     8         |   20    | ... 
city2 :     15        |        12          |     35        |   10    |  ...  
city3 :     1         |        35          |     3         |   8     |  ...  

And then I have my function. In it, what I'd like to do is calculate the percentage of people with a lower and equal education / people with higher education.

Example: if user1 is from city2 and has an apprenticeship degree it would result as 62 / 38 = 1.63

This is what I have got until now, but as you can see, it is a massive flop:

def edu_score(education, fos, province, city):
    edu_lvl = ['No_certificate', 'high_school_diploma', 'Apprenticeship', 'CEGEP', 'Bachelor Diploma', 'Master Diploma', 'Doctorate']
    score = 0 
    crsr.execute("SELECT (SUM([edu_lvl.index(ed):: -1]) / (SUM ([edu_lvl.index(ed)::])) FROM province_1 WHERE cities = city") 
    score = crsr.fetchone()         
    print score

How do I calculate it? and how do I do so that the user's input is not taken as a string, which returns that same string value in the db?

Thank you so much, and I hope I was clear enough.

First you should merge your tables into one, and add a column called provinces. There is a strong reason for that. You do not want any user input field being called as a table name since you can't easily tokenize it (avoid sql injection).

Second you are merging python code with a SQL statement, so that will never work.

What you need is something like this:

def edu_score(education, fos, province, city):
    score = 0
    crsr.execute('SELECT (SUM("no certificate"+"high school diploma"+"Apprenticeship") / (SUM ("Bachelor Diploma"+"Master Diploma"+"Doctorate")) FROM provinces WHERE cities = ? AND province = ?', city, province)
    score = crsr.fetchone()
    return score

UPDATED: To handle the scoring you should do it in python, not SQL.

def edu_score(education, fos, province, city):
    eds = ['No_certificate', 'high_school_diploma', 'Apprenticeship', 'CEGEP', 'Bachelor Diploma', 'Master Diploma', 'Doctorate']
    ed_index = eds.index(education)
    crsr.execute('SELECT SUM("no certificate"), SUM("high school diploma"), SUM("Apprenticeship"), SUM ("Bachelor Diploma"), SUM("Master Diploma"), SUM("Doctorate") FROM provinces WHERE cities = ? AND province = ?',
        city, province)
    scores = crsr.fetchone()
    score = sum(scores[:ed_index])/sum(scores[ed_index:])
    return score

[MY ANSWER]

So the first problem I had was that I was adding another string into the SELECT statement through edu_score(education), which only returned the string found in the DB. The other problem was that it wasn't summing just the necessary rows, depending on the user's highest level of education.

The answer was this: segment the SELECT string and do not use the SUM, as it is summing column and not rows. You just need to make a string that encompasses all the data you want to add ie : SELECT (A + B + C) FROM table WHERE ?, [city,] .

phrase = ''

I made this variable because within the function it would return 'None'

def city_result(base):   
    global phrase 
    edu_lvl = ['No_certificate', 'high_school_diploma', 'Apprenticeship', 'CEGEP', 'Bachelor', 'Master', 'Doctorate']
    for i in  edu_lvl[edu_lvl.index(base):: -1] :
        if edu_lvl.index(i) == 0:
            phrase = phrase + i
        else: 
            phrase = i + " + " + phrase

city_result is what will be put in the SELECT statement to be counted

def edu_score(education, fos, province, city):
    global phrase
    score = 0 
    city_result(education)
    crsr.execute("SELECT (" + phrase + ") FROM ? WHERE cities = ?", [province, city,]) 
    score = crsr.fetchone()
    score = score / (100 - score)

The only thing to remember is that SUM is for column, so if you just want certain row, just put the data you want to add within the SELECT statement, and be careful with putting string in the SELECT string (because it returns that same string).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM