database.py
7.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
import logging
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session
from orm import Base, Student, Test, Question
logger = logging.getLogger(__name__)
#----------------------------------------------------------------------------
class Database(object):
def __init__(self, db):
self.db = db # sqlite3 filename
engine = create_engine('sqlite:///{}'.format(db), echo=False)
Base.metadata.create_all(engine) # Criate schema if needed
self.Session = scoped_session(sessionmaker(bind=engine))
#-------------------------------------------------------------------------
def get_count_students(self):
s = self.Session()
return s.query(Student).filter(Student.id != '0').count()
# with sqlite3.connect(self.db) as c:
# sql = 'SELECT COUNT(*) FROM students'
# return c.execute(sql).fetchone()[0]
#-------------------------------------------------------------------------
def update_password(self, uid, pw=''):
s = self.Session()
try:
u = s.query(Student).filter(Student.id == uid).one()
except:
pass
else:
u.password = pw
s.commit()
# saves pw as is (should be already hashed)
# with sqlite3.connect(self.db) as c:
# sql = 'UPDATE students SET password=? WHERE id=?'
# c.execute(sql, (pw, uid))
#-------------------------------------------------------------------------
def get_student(self, uid):
s = self.Session()
r = s.query(Student).filter(Student.id == uid).one_or_none()
return r.name, r.password
# with sqlite3.connect(self.db) as c:
# sql = 'SELECT name,password FROM students WHERE id=?'
# try:
# name, pw = c.execute(sql, [uid]).fetchone()
# except:
# return None
# else:
# return (name, pw)
#-------------------------------------------------------------------------
def get_all_students(self):
s = self.Session()
r = s.query(Student).all()
return [(x.id, x.name, x.password) for x in r]
# with sqlite3.connect(self.db) as c:
# sql = 'SELECT id,name,password FROM students ORDER BY id ASC'
# students = c.execute(sql).fetchall()
# return students
# get all results for a particular test. If a student has submited more than
# one test, returns the highest grade FIXME not tested, not used
# def get_students_grades(self, testid):
# with sqlite3.connect(self.db) as c:
# grades = c.execute('SELECT student_id,MAX(grade) FROM tests WHERE test_id==?', [testid])
# return grades.fetchall()
#-------------------------------------------------------------------------
# get results from previous tests of a student
def get_student_grades_from_all_tests(self, uid):
s = self.Session()
r = s.query(Test).filter(Student.id == uid).all()
return [(x.id, x.grade, x.finishtime) for x in r]
# with sqlite3.connect(self.db) as c:
# grades = c.execute('SELECT id,grade,finishtime FROM tests WHERE student_id==?', [uid])
# return grades.fetchall()
#-------------------------------------------------------------------------
def get_student_grades_from_test(self, uid, testid):
s = self.Session()
r = s.query(Test).filter(Test.student_id==uid and Test.id==testid).all()
return [(x.grade, x.finishtime) for x in r]
# with sqlite3.connect(self.db) as c:
# grades = c.execute('SELECT grade,finishtime FROM tests WHERE student_id==? and id==?', [uid, testid])
# return grades.fetchall()
#-------------------------------------------------------------------------
def save_test(self, test):
t = Test(
ref=test['ref'],
grade=test['grade'],
starttime=str(test['start_time']),
finishtime=str(test['finish_time']),
student_id=test['student']['number']
)
s = self.Session()
s.add(t)
s.commit()
# with sqlite3.connect(self.db) as c:
# # save final grade of the test
# sql = 'INSERT INTO tests VALUES (?,?,?,?,?)'
# test = (t['ref'], t['student']['number'], t['grade'], str(t['start_time']), str(t['finish_time']))
# c.execute(sql, test)
#-------------------------------------------------------------------------
def save_questions(self, test):
s = self.Session()
questions = [Question(
ref=q['ref'],
grade=q['grade'],
starttime='',
finishtime=str(test['finish_time']),
student_id=test['student']['number'],
test_id=test['ref']) for q in test['questions'] if 'grade' in q]
s.add_all(questions)
s.commit()
# with sqlite3.connect(self.db) as c:
# # save grades of all the questions (omits questions without grade)
# sql = 'INSERT INTO questions VALUES (?,?,?,?,?)'
# questions = [(t['ref'], q['ref'], t['student']['number'], q['grade'], str(t['finish_time'])) for q in t['questions'] if 'grade' in q]
# c.executemany(sql, questions)
# def insert_student(self, number, name, password=''): # FIXME testar...
# with sqlite3.connect(self.db) as c:
# if password != '':
# password = sha256(password.encode('utf-8')).hexdigest() # FIXME bcrypt
# cmd = 'INSERT INTO students VALUES (?, ?, ?);'
# c.execute(cmd, number, name, password)
# # return list of students and their results for a given test
# def get_test_grades(self, test_id):
# with sqlite3.connect(self.db) as c:
# # with all tests done by each student:
# # cmd = 'SELECT student_id,name,grade FROM students INNER JOIN tests ON students.number=tests.student_id WHERE test_id==? ORDER BY grade DESC;'
# # only the best result for each student
# cmd = '''
# SELECT student_id, name, MAX(grade), finish_time
# FROM students INNER JOIN tests
# ON students.number=tests.student_id
# WHERE test_id==? AND student_id!=0
# GROUP BY student_id
# ORDER BY grade DESC, finish_time DESC;'''
# return c.execute(cmd, [test_id]).fetchall()
# # return list of students and their results for a given test
# def test_grades2(self, test_id):
# with sqlite3.connect(self.db) as c:
# # with all tests done by each student:
# # cmd = 'SELECT student_id,name,grade FROM students INNER JOIN tests ON students.number=tests.student_id WHERE test_id==? ORDER BY grade DESC;'
# # only the best result for each student
# cmd = '''
# SELECT student_id, name, grade, start_time, finish_time
# FROM students INNER JOIN tests
# ON students.number=tests.student_id
# WHERE test_id==?
# ORDER BY finish_time ASC;'''
# return c.execute(cmd, [test_id]).fetchall()
# the following methods update de database data