В Python я читаю строки из sqlite3 в объект, который представляет собой простую структуру данных. В момент назначения мне нужно присвоить строку ряду переменных. Есть ли способ сделать это проще?
Я включил пример кода ниже, который, надеюсь, иллюстрирует мою проблему.
import sqlite3
class studentDef(object):
def __init__(self):
self.firstName = 'x'
self.lastName = 'x'
self.id = 'x'
self.address1 = 'x'
self.address2 = 'x'
self.city = 'x'
self.state = 'x'
self.zip = 'x'
self.status = 0
def main():
mystudent = studentDef()
db = sqlite3.connect('students.sqlite3')
cursor = db.cursor()
selectTxt = "select * from students where status = 1"
cursor.execute(selectTxt)
rows = cursor.fetchall()
for index in range(0,len(rows)):
mystudent.firstName, mystudent.lastName, mystudent.id, mystudent.address1, \
mystudent.address2, mystudent.city, mystudent.state, mystudent.zip, \
mystudent.status = row[index]
processStudent(mystudent)
if __name__ == '__main__':
main()
Мой текущий код читается в столбцах 50+, и оператор присваивания становится немного волосатым! Поскольку я все еще разрабатываю, я постоянно возился с оператором присваивания при добавлении, удалении или изменении столбцов.
Есть ли более простой способ сделать что-то вроде:
mystudent = row[index]
Моя другая проблема заключается в том, что я делаю это примерно в 5 других программах. Поэтому каждый раз, когда я изменяю макет базы данных, я трачу много времени на обновление всего моего кода.
Проблема заключается в том, как вы написали инициализатор класса. Класс должен нести ответственность за настройку собственных данных; нет смысла писать функцию init, которая устанавливает атрибуты для хранения значений, а затем полагается на процесс вне класса, чтобы установить их в фактические значения. Так:
class studentDef(object):
def __init__(self, firstName, lastName, id, address1, address2, city, state, zip, status):
self.firstName = firstName
self.lastName = lastName
self.id = id
self.address1 = address1
self.address2 = address2
self.city = city
self.state = state
self.zip = zip
self.status = status
Теперь вы можете просто пройти в строке, используя синтаксис *
чтобы развернуть список по отдельным параметрам:
cursor.execute(selectTxt)
for row in cursor:
mystudent = studentDef(*row)
(обратите внимание, что в Python вы почти никогда не будете перебирать range(len(something))
, всегда перебирайте самую вещь).
Это также звучит так, как processStudent
должен быть методом класса studentDef. Наконец, обратите внимание, что стиль Python должен использовать InitialCaps для классов, а lower_case_with_underscore для атрибутов: StudentDef, first_name, last_name.
Вы можете использовать инструмент объектно-реляционного сопоставления (ORM). Такой инструмент отобразит вашу базу данных SQLite3 в объекты Python (и наоборот), уменьшив количество кода.
Вот пример использования peewee:
from peewee import *
db = SqliteDatabase('students.sqlite3')
class Student(Model):
first_name = CharField()
last_name = CharField()
address1 = CharField()
address2 = CharField()
city = CharField()
state = CharField()
zip = CharField()
status = SmallIntegerField()
class Meta:
database = db
Затем вы можете обратиться к своим ученикам с помощью:
>>> query = Student.select()
>>> [student.first_name for student in query]
['Charlie', 'Huey', 'Peewee']
>>> query[1]
<__main__.Student at 0x7f83e80f5550>
>>> query[1].first_name
'Huey'
Существуют и другие ORM Python, совместимые с SQLite: SQLAlchemy, Django Models (для создания веб-приложений) и, возможно, многие другие.