DB구조가 바뀔 때 항목들이 추가/삭제되어야 하는 부분.
이번에는 항목 추가에 대한 부분.
https://cloud.google.com/appengine/articles/update_schema
페이지에 사실 너무 잘 적혀있다.
아래는 내 프로젝트에 맞게 수정
모델이 다음과 같이 바뀔 때
# -*- coding: utf-8 -*- import os import urllib from google.appengine.api import users from google.appengine.ext import ndb import jinja2 import webapp2 CD_KEY = 'cd_key' def cd_key(): return ndb.Key('key',CD_KEY) class AlbumModel(ndb.Model): artist = ndb.StringProperty() title = ndb.StringProperty(indexed=False) label = ndb.StringProperty() user = ndb.UserProperty() created_at = ndb.DateTimeProperty(auto_now_add=True) updated_at = ndb.DateTimeProperty() last_login = ndb.DateTimeProperty(auto_now=True) #Add (2014.12.06) version = ndb.IntegerProperty(default=2)
이전 entity들에 version을 1로 넣고 싶다고 할 때 다음과 같이 새로운 모듈을 만들어서 진행하는 방식이다.
import logging import model import webapp2 from google.appengine.ext import deferred def UpdateSchema(): num_updated = 0 albums_query = model.AlbumModel.query() for p in albums_query.fetch(): #logging.debug(p) p.version = 1 p.put() num_updated+=1 logging.debug( 'UpdateSchema complete with %d updates!', num_updated) class UpdateHandler(webapp2.RequestHandler): def get(self): deferred.defer(UpdateSchema) self.response.out.write('Schema migration successfully initiated.') app = webapp2.WSGIApplication([('/update_schema', UpdateHandler)])
구글 페이지의 예제에서 재미있는 부분은,
deferred.defer( UpdateSchema, cursor=query.cursor(), num_updated=num_updated)
이다. deferred.defer라는 함수는 일종의 독립 모듈로 함수를 시행시킨다는 것인데, (일종의 multi-thread 같은 것으로 볼 수 있을까) 예를 들어 업데이트 해야하는 DB의 항목이 너무 많다면, 결국 갯수를 끊어서 시행해야한다는 것이고,
def UpdateSchema(cursor=None, num_updated=0):
query = models.Picture.all()
if cursor:
query.with_cursor(cursor)
.
생략
.
for p in query.fetch(limit=BATCH_SIZE):
이전에 사용했던 cursor를 다시 함수로 넘겨줌으로서, 그 이후 부터 BATCH_SIZE 만큼 불러오고, 다시 defer함수로 뒷부분을 시행시키는 방식으로 진행되는 것 같다.
만약 db가 아니라 ndb를 사용하고 있다면,
https://cloud.google.com/appengine/docs/python/ndb/queries#cursors
페이지에 cursor를 이용하는 방식이 잘 설명되어있다.