0

當我運行此如果塊:查詢數據存儲:「NoneType」對象沒有屬性

first_query = db.GqlQuery("SELECT * FROM Contract ORDER BY date DESC").get() 
    if first_query == None: 
     numBook = 42 
     numInitialPage = 42 
     numFinalPage = 42 
     first_record = Contract(book_number = 1, initial_page = 0, final_page = 0) 
     first_record.put() 
     contract = db.GqlQuery("SELECT * FROM Contract ORDER BY date DESC").get() 
     numBook = contract.book_number 
     numInitialPage = contract.final_page +1 
     numFinalPage = numInitialPage 
    else: 
     contract = first_query 
     numBook = first_query 
     numInitialPage = 51 
     numFinalPage = 51 

過程跳轉到if塊,但是,後來,我收到此錯誤信息:

File "C:\Users\CG\Documents\udacity\contract\main.py", line 88, in get 
    numBook = contract.book_number 
AttributeError: 'NoneType' object has no attribute 'book_number' 

由於我用.put()來插入一條記錄,而.get()做了一個處理,爲什麼合同的價值是None

在此先感謝您的幫助!

這裏整個代碼:

# -*- coding: utf-8 -*- 
# -*- coding: utf-8 -*- 
#!/usr/bin/env python 
# 
# Copyright 2007 Google Inc. 
# 
# Licensed under the Apache License, Version 2.0 (the "License"); 
# you may not use this file except in compliance with the License. 
# You may obtain a copy of the License at 
# 
#  http://www.apache.org/licenses/LICENSE-2.0 
# 
# Unless required by applicable law or agreed to in writing, software 
# distributed under the License is distributed on an "AS IS" BASIS, 
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
# See the License for the specific language governing permissions and 
# limitations under the License. 
# 

import os 

import webapp2 

import jinja2 

jinja_environment = jinja2.Environment(autoescape=True, 
    loader=jinja2.FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates'))) 

import re 

from google.appengine.ext import db 

USER_RE = re.compile(r"^[a-zA-Z0-9_ -]{3,20}$") 
def valid_person(person): 
    return USER_RE.match(person) 

PASS_RE = re.compile(r"^.{3,20}$") 
def valid_SSN(SSN): 
    return PASS_RE.match(SSN) 

EMAIL_RE = re.compile(r"^[\S][email protected][\S]+\.[\S]+$") 
def valid_email(email): 
    return EMAIL_RE.match(email) 

import time 

import datetime 

def dateToday(): 
    today = datetime.datetime.today() 
    todayDay = str(today.day) 
    todayMonth = str(today.month) 
    monthExt = {'1':' January ', '2':'February', '3':' March ', '4':'April', '5':'May', '6':'June', '7':' July ', '8':'August', '9':'September', '10':'October', '11':'November ', '12':'December'} 
    todayYear = str(today.year) 
    return(todayDay + ' of ' + monthExt[todayMonth] + ' of ' + todayYear) 

class Person(db.Model): 
    firstName = db.StringProperty(required = True) 
    nacionality = db.StringProperty(required = True) 
    marital_status = db.StringProperty(required = True) 
    profession = db.StringProperty(required = True) 
    SSN = db.IntegerProperty(required = True) 
    driver_license = db.IntegerProperty(required = True) 
# address = db.PostalAddress(required = False) 

class Contract(db.Model): 
    book_number = db.IntegerProperty(required = True) 
    initial_page = db.IntegerProperty(required = True) 
    final_page = db.IntegerProperty(required = True) 
## contrac_type = db.StringProperty(required = False, choices=set(["Purchase Agreement", "Rental House", "Rental Car"])) 
## contract_place = db.StringProperty(required = False) 
## contract_date = db.DateProperty (required = True, auto_now = True, auto_now_add = True) 

class ContractingParty(db.Model): 
    person = db.ReferenceProperty(Person, required=True, collection_name="party_to_contracts") 
    condition = db.StringProperty(required = False, choices=set(["buyer", "seller", "renter", "owner", "witness"])) 

class MainHandler(webapp2.RequestHandler): 
    def get(self): 
     first_query = db.GqlQuery("SELECT * FROM Contract ORDER BY date DESC").get() 
     if first_query == None: 
      numBook = 8 
      numInitialPage = 8 
      numFinalPage = 8 
      first_record = Contract(book_number = 1, initial_page = 0, final_page = 0) 
      first_record.put() 
      contract = db.GqlQuery("SELECT * FROM Contract ORDER BY date DESC").get() 
      numBook = contract.book_number 
      numInitialPage = contract.final_page +1 
      numFinalPage = numInitialPage 
     else: 
      contract = first_query 
      numBook = first_query 
      numInitialPage = 7 
      numFinalPage = 7 

##  numBook = contract.book_number 
##  numInitialPage = contract.final_page +1 
##  numFinalPage = numInitialPage 
     template_values = {"person": "", 
             "nacionality": "", 
             "SSN": "", 
             "driverLicense": "", 
             "email":"", 
             "person_error": "", 
             "SSN_error": "", 
             "driverLicense_error": "", 
             "address": "", 
             "email_error": "", 
             "numBook": numBook, 
             "numInitialPage": numInitialPage, 
             "numFinalPage": numFinalPage, 
             } 
     template = jinja_environment.get_template('index.html') 
     self.response.out.write(template.render(template_values)) 

    def post(self): 
     person_name = self.request.get("person") 
     user_nacionality = self.request.get('nacionality') 
     user_profession = self.request.get('profession') 
     user_maritalStatus = self.request.get('maritalStatus') 
     user_SSN = self.request.get('SSN') 
     user_email = self.request.get('email') 
     user_driverLicense = self.request.get('driverLicense') 
     person_error = "" 
     SSN_error = "" 
     driverLicense_error = "" 
     geted_email_error = "" 
     address = self.request.get('address') 
     contractType = self.request.get("contractType") 
     owner = self.request.get("owner") 
     witness = self.request.get("witness") 
     numBook = self.request.get("numBook") 
     numInitialPage = self.request.get("numInitialPage") 
     numFinalPage = self.request.get("numFinalPage") 

     if (person_name and valid_person(person_name)) and (user_SSN and valid_SSN(user_SSN)) and ((not user_email) or (user_email and valid_email(user_email))): 
      contract_record = Contract(book_number = numBook, initial_page = numInitialPage, final_page = numFinalPage) 
      contract_record.put() 
      contract_id = contract_record.key().id() 
      person_record = Person(name = person_name, 
           nacionality = user_nacionality, 
           profession = user_profession, 
           marital_status = user_maritalStatus, 
           SSN = int(user_SSN), 
           driverLicense = int(user_driverLicense)) 
      person_record.put() 
# HERE THE PROBLEM - Contracting party should be a table with ID refering to contract table 
#  contracting_party_record = ContractingParty(person = 1, ) 
##   person = db.ReferenceProperty(People, required=True, collection_name="party_to_contracts") 
##   condition = db.StringProperty(required = False, choices=set(["buyer", "seller", "renter", "owner", "witness"])) 
##   self.redirect('/your_contract?person=%s&nacionality=%s&profession=%s&maritalStatus=%s&SSN=%s&driverLicense=%s&email=%s&witness=%s&owner=%s&contractType=%s&address=%s&numBook=%s&numInitialPage=%s&numFinalPage=%s' % (person_name, user_nacionality, user_profession, user_maritalStatus, user_SSN, user_driverLicense, user_email, 
##witness, owner, contractType, address, numBook, numInitialPage, numFinalPage)) 
      self.redirect('/your_contract?person=%s' % contract_id) 

     else: 
      if not person_name or not valid_person(person_name): 
       person_error = "Oh no!!! this person name isn't valid!" 
      if not user_SSN or not valid_SSN(user_SSN): 
       SSN_error = "Oh no!!! SSN isn't valid!" 
      if user_email and not valid_email(user_email): 
       geted_email_error = "Oh no!!! e-mail isn't valid!" 
      template_values = {"person": person_name, 
           "nacionality": user_nacionality, 
           "maritalStatus": user_maritalStatus, 
           "profession": user_profession, 
           "SSN": user_SSN, 
           "driverLicense": user_driverLicense, 
           "email": user_email, 
           "person_error": person_error, 
           "SSN_error": SSN_error, 
           "driverLicense_error": user_driverLicense, 
           "address": address, 
           "email_error": geted_email_error} 
      template = jinja_environment.get_template('index.html') 
      self.response.out.write(template.render(template_values)) 

class your_contractHandler(webapp2.RequestHandler): 
    def get(self): 
     contract_id = self.request.get('contract_id') 
     contract = db.GqlQuery("SELECT * FROM Contract WHERE __key__ = KEY('Model', contract_id").get() 
##  SELECT * FROM Model where __key__ = KEY('Model', <numeric_id>) 
     geted_numBook = contract.book_number 
     geted_numInitialPage = contract.initial_page 
     geted_numFinalPage = contract.final_page 
     geted_dateToday = dateToday() 
     geted_contractType = contract.contract_type 

     person = db.GqlQuery("SELECT * FROM Person ORDER BY date DESC").get() 
     geted_person_name = person.name 
     geted_user_nacionality = person.nacionality 
     geted_user_profession = person.profession 
     geted_user_maritalStatus = person.marital_status 
     geted_user_SSN = person.SSN 
     geted_user_driver_license = person.driver_license 


     your_contract = jinja_environment.get_template('your_contract.html') 

     your_contract_values = {"person":geted_person_name, 
           "nacionality":geted_user_nacionality, 
           "maritalStatus": geted_user_marital_status, 
           "profession": geted_user_profession, 
           "SSN":geted_user_SSN, 
           "driverLicense":geted_user_driver_license, 
           "address":geted_address, 
           "email":geted_user_email, 
           "contractType":geted_contract_type, 
           "dateContract":geted_dateToday, 
           "numBook":geted_numBook, 
           "numInitialPage":geted_numInitialPage, 
           "numFinalPage":geted_numInitialPage, 
           } 
     template = jinja_environment.get_template('index.html') 
     self.response.out.write(your_contract.render(your_contract_values)) 


# ContractingParty.all().ancestor(thecontract).run() 
# contract_id = contract.key().id() 
# contract_parties = Contract.get_by_id(contract_id) 
#http://stackoverflow.com/questions/11294526/how-to-model-a-contract-database-with-several-buyers-or-sellers-using-gae-data 
#http://stackoverflow.com/questions/11311461/how-to-query-gae-datastore-to-render-a-template-newbie-level 
app = webapp2.WSGIApplication([('/', MainHandler), ('/your_contract', your_contractHandler)], 
           debug=True) 
+0

謝謝,@NedBatchelder,剛剛完成! – craftApprentice 2012-07-09 02:43:15

+0

它在[GAE文檔](https://developers.google.com/appengine/docs/python/datastore/gqlqueryclass#GqlQuery_get)中說,如果沒有找到結果,'GqlQuery.get()'返回'None'。 – 2012-07-09 02:48:44

+0

問題是:如果我只是把合同寫入一個新記錄,怎麼會有沒有結果:'first_record = Contract(book_number = 1,initial_page = 0,final_page = 0) first_record.put()'? – craftApprentice 2012-07-09 02:53:37

回答

1

因爲你沒有在你的合同模型date場,所以不返回任何結果。

由於數據存儲是無模式的,因此GQL無法知道模型中的任何實體是否可能具有特定的字段。所以,與SQL不同的是,當你引用一個不存在的字段時,它不會引發錯誤:它只是執行查詢,如果沒有找到,它不會返回任何內容。

我不知道爲什麼你想在任何情況下查詢它。即使你做了,你也應該通過調用返回的關鍵字來獲得它,而不是做一個查詢:最終的一致性模型意味着數據可能不會被下一條語句完全保留,所以查詢不會看到它,而直接獲取按鍵始終保證這樣做。

+0

感謝您的回答和建議。我將使用key_id。 – craftApprentice 2012-07-09 12:28:52

相關問題