티스토리 뷰


* 이번에는 약간 이론과 실제 구현을 섞어서 한번 프로젝트를 진행해보자. 공부할 내용은 Python과 구글 앱엔진을 통해서 자료 구조를 구축하는 방법에 대해서 공부하면서 진행할 것이다. 1:1, 1:N, 그리고 N:M의 관계들에 대해서 알아보고 서버측 데이터 설계를 완성할 것이다.


* 공부하면서 구현하는 것이고 테스트를 차후에 기능들을 구현하면서 할 것이기 때문에 문법상, 구조상 다소 오류가 있을 수 있습니다.


- 이전 관련 글들..

2012/10/06 - [NY-School] Google App Engine과 Python 시작하기전에 공부하기

2012/10/06 - [NY-School] Google App Engine과 Python 시작하기 - Hello world

2012/10/06 - [NY-School] Google App Engine과 Python 시작하기 - webapp framework

2012/10/07 - [NY-School] Google App Engine과 Python 시작하기 - Datastore 사용해서 방명록 만들기

2012/10/20 - [NY-School] Google App Engine과 Python 시작하기 - Template페이지 사용하기

2012/11/02 - [NY-School] Google App Engine과 Python 시작하기 - Static 페이지 사용하기

2012/11/02 - [NY-School] Google App Engine과 Python 시작하기 - 서버에 올리기(Deploy)

2012/11/03 - [NY-School] 기본 기능과 데이터구조 설계

2012/11/10 - [NY-School] 데이터 구조 자바스크립트 구현



* 1:N 관계 (1:1 관계)

: 일단 이전에 자바스크립트로 명시했던 데이터구조에 맞춰서 한번 설계를 진행해보자. 가장 핵심이 되는 것은 바로 학생이므로 학생부터 만들어보자.

class Student(db.Model): studentName = db.StringProperty(required=True) studentBirthday = db.DateProperty() studentPhoneNumber = db.PhoneNumberProperty() studentEmail = db.EmailProperty() studentMemo = db.StringProperty(multiline=True) madeBy = db.ReferenceProperty(User, required=True)

: 일단 다른 외부 관계를 고려안하고 많은 부분은 스트링으로 해결을 하고 있다. 이제부터 관계를 추가하고 여러 가지 생각을 해보자. 여기의 madeBy는 학생을 등록시킨 사람의 정보가 들어가야하므로, 학생을 등록한 사람과 학생을 연결시켜보자. 일단 학생을 등록한 유저 클래스도 만들자. 

class User(db.Mobel):
	userName = db.UserProperty()
	school = db.StringProperty()
	homeRoom = db.StringProperty()
	studentList = db.ListProperty(db.Key)


등록한 사람과 학생의 관계는 1:N으로 등록한 User가 위처럼 학생의 목록을 가지고 있을 수 있지만, 반대로 학생이 madeBy를 통해서 User의 id를 가지고 있을수도 있다. 어느쪽이 유용한지는, User에서 Student으로 자주 접근을 하느냐, Student에서 User로 자주 접근을 하느냐의 문제로 고민을 해보면 될 것이다. 하지만 지금 생각하는 경우는 학생에서 사용자로, 사용자에서 학생으로 직접가는 경우는 드물것이라고 예상하고 있기 때문에 다른 방법을 사용해보겠다.

class Student(db.Model): studentName = db.StringProperty(required=True) studentBirthday = db.DateTimeProperty() studentPhoneNumber = db.PhoneNumberProperty() studentEmail = db.EmailProperty() studentPhoto = db.BlobProperty() studentMemo = db.StringProperty(multiline=True) class User(db.Mobel): user = db.UserProperty() school = db.ReferenceProperty(School) homeRoom = db.ReferenceProperty(HomeRoom) def addStudent(currentUser, studentName, studentBirthday=None, studentPhoneNumber=None, studentEmail=None, studentPhoto=None,studentMemo=None): student = Student(parent=currentUser studentName=studentName, studentBirthday=studentBirthday, studentPhoneNumber=studentPhoneNumber, studentEmail=studentEmail, studentPhoto=studentPhoto, studentMemo=studentMemo) student.put()


: 위와 같이 addStudent라는 함수를 추가해서 저장하는 함수를 구현해보았다. parent=currentUser를 설정함으로써 currentUser가 Student의 부모가 된 것을 알 수 있다. 1:N의 계층적인 구조에서는 이러한 방법을 사용하는 것이 효과적일 것이다. 이렇게 parent로 설정하고나면, 아래처럼 학생들을 쿼리할 수 있다.

def getStudents():
	user = User.all().filter('user = ', users.get_current_user())
	return Student.all().ancestor(user)


: 위의 Student가 madeBy를 가지는 방식은 1:1 방식에서도 충분히 활용가능한 방식이고, parent를 설정해줌으로써 ancestor를 지정해주는 것은 1:N 관계에서 쉽게 구현할 수 있는 방법이다.


N:M 관계

: 이번에는 N:M 관계를 알아보자. 학생의 목록과 학생의 관계가 바로 N:M 관계이다. 그럼 학생 목록 클래스를 구현해보자.

class StudentList(db.Model): studentListName = db.StringProperty(required=True) studentList = db.ListProperty(db.Key) description = db.StringProperty(multiline=True)

: 위와 같이 구현을 해보았다. 이렇게 구현한 것은 Student에서 StudentList로 검색하는 경우가 별로 없고, StudentList에서 Student를 참조하는 경우가 많기 때문이다. 만약 양방향으로 조회를 자주하는 경우라면, 하나의 클래스를 더 추가해서 중간에서 이어주는 역할을 하는 것이 좋을 것이다.


: 그렇다면 이제 나머지 School과 HomeRoom, Teacher클래스를 만들고 간단하게 저장하고 불러오는 함수들을 구현해보면 아래와 같이 될 것이다.

class User(db.Model):
	user = db.UserProperty()
	school = db.ReferenceProperty(School)
	homeRoom = db.ReferenceProperty(HomeRoom)

def putUser(school=None, homeRoom=None):
	user = User(user=users.get_current_user(), school=school, homeRoom=homeRoom)
	user.put()
	return user

def getUser():
	return User.all().filter('user = ', users.get_current_user())


class Student(db.Model):
	studentName = db.StringProperty(required=True)
	studentBirthday = db.DateTimeProperty()
	studentPhoneNumber = db.PhoneNumberProperty()
	studentEmail = db.EmailProperty()
	studentPhoto = db.BlobProperty()
	studentMemo = db.StringProperty(multiline=True)
	studentSchool = db.ReferenceProperty(School)

def addStudent(studentName, studentBirthday=None, studentPhoneNumber=None, studentEmail=None, studentPhoto=None,studentMemo=None):
	user = User.all().filter('user = ', users.get_current_user())
	student = Student(parent=user,
		studentName=studentName,
		studentBirthday=studentBirthday,
		studentPhoneNumber=studentPhoneNumber,
		studentEmail=studentEmail,
		studentPhoto=studentPhoto,
		studentMemo=studentMemo)
	student.put()
	return student

def getStudents():
	user = User.all().filter('user = ', users.get_current_user())
	return Student.all().ancestor(user)



class StudentList(db.Model):
	studentListName = db.StringProperty(required=True)
	studentList = db.ListProperty(Student)
	description = db.StringProperty(multiline=True)

def addStudentList(studentListName, students=None, description=None):
	user = User.all().filter('user = ', users.get_current_user())
	studentList = StudentList(parent=user,
		studentListName=studentListName,
		studentList=students,
		description=description)
	studentList.put()
	return studentList

def getStudentLists():
	user = User.all().filter('user = ', users.get_current_user())
	return StudentList.all().ancestor(user)



class Teacher(db.Model):
	teacherName = db.StringProperty(required=True)
	teacherSubject = db.ReferenceProperty(Subject)
	teacherPhoneNumber = db.PhoneNumberProperty()
	teacherEmail = db.EmailProperty()
	homeRoom = db.ReferenceProperty(HomeRoom)

def putTeacher(teacherName, teacherSubject=None, teacherPhoneNumber=None, teacherEmail=None, homeRoom=None):
	user = User.all().filter('user =', users.get_current_user())
	teacher = Teacher(parent=user, teacherName=teacherName, teacherSubject=teacherSubject, teacherPhoneNumber=teacherPhoneNumber, teacherEmail=teacherEmail, homeRoom=homeRoom)
	teacher.put()
	return teacher

def getTeachers():
	user = User.all().filter('user = ', users.get_current_user())
	return Teacher.all().ancestor(user)


class HomeRoom(db.Model):
	studentList = db.ReferenceProperty(StudentList)
	homeRoomName = db.StringProperty(required=True)
	homeRoomSchool = db.ReferenceProperty(School)
	homeRoomGrade = db.IntegerProperty()
	homeRoomNumber = db.IntegerProperty()
	homeRoomTeacher = db.ReferenceProperty(Teacher)
	homeRoomYear = db.IntegerProperty()
	homeRoomMemo = db.StringProperty(multiline=True)


def putHomeRoom(studentList=None, homeRoomName, homeRoomSchool=None, homeRoomGrade=None, homeRoomNumber=None, homeRoomTeacher=None, homeRoomYear=None, homeRoomMemo=None):
	user = User.all().filter('user =', users.get_current_user())
	homeRoom = HomeRoom(parent=user, studentList=studentList, homeRoomName=homeRoomName, homeRoomSchool=homeRoomSchool, homeRoomGrade=homeRoomGrade, homeRoomNumber=homeRoomNumber, homeRoomTeacher=homeRoomTeacher, homeRoomYear=homeRoomYear, homeRoomMemo=homeRoomMemo)
	homeRoom.put()
	return homeRoom


def getHomeRooms():
	user = User.all().filter('user = ', users.get_current_user())
	return HomeRoom.all().ancestor(user)


class School(db.Model):
	schoolName = db.StringProperty(required=True)
	schoolType = db.StringProperty()

def putSchool(schoolName, schoolType=None):
	user = User.all().filter('user =', users.get_current_user())
	school = School(parent=user, schoolName=schoolName, schoolType=schoolType)
	school.put()
	return school

def getSchools():
	user = User.all().filter('user = ', users.get_current_user())
	return School.all().ancestor(user)


class Subject(db.Model):
	subjectName = db.StringProperty(required=True)

def putSubject(subjectName):
	user = User.all().filter('user =', users.get_current_user())
	subject = Subject(parent=user, subjectName=subjectName)
	subject.put()
	return subject

def getSubjects():
	user = User.all().filter('user = ', users.get_current_user())
	return Subject.all().ancestor(user)


: 일단 모든 클래스는 User에 dependent하므로 User를 parent로 가지고, 사용자가 목록을 접근할 때에는 일단 User를 ancestor로 가지는 목록만 접근을 하도록 할 것이다. 


: 사실 이렇게 작성한 구조가 잘 작동할지는 아직 잘 모르겠다. 다음에는 일단 간단하게 사용자를 등록하는 페이지를 한번 작성해봐야겠다.


끝.


공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
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
글 보관함