Google Cloud Ndb报错:'Key'对象无'database'属性(Python3.9+GAE)
问题分析与解决方案
问题描述
基于Python 3.9运行Google App Engine应用,采用Cloud Ndb作为数据库,customer模型创建实体正常,但执行实体更新时抛出如下错误:
AttributeError at /customer/edit/6199943289110528
'Key' object has no attribute 'database'
创建客户代码:
newCustomer = customer( number = number, addedBy = ndb.Key('employee',int(employeeId)), firstName = firstname, lastName = lastname, phone = phone, countryCode= countryCode) order_key = newCustomer.put()
更新客户代码:
customer = ndb.Key('customer',customer_id).get() customer.firstName = firstName customer.lastName = lastName customer.phone = phone customer.countryCode = countryCode customer_key = customer.put()
原因分析
最可能的原因是变量名与模型类名冲突:你的模型类名为customer,但在更新代码中,你将同一个变量名customer赋值给了从数据库获取的实体实例。这会导致Cloud Ndb内部执行put()操作时,混淆模型类与实体实例的引用,触发异常。
此外还可能存在次要因素:
customer_id类型不匹配(比如传入字符串而非实体实际的整数ID),导致get()返回None,引发连锁错误- Cloud Ndb版本存在已知bug,或请求上下文未正确初始化
解决方案
1. 避免变量名与模型类名冲突
修改更新代码中的变量名,改用不与模型类名重复的名称,并增加空值判断避免None操作:
# 改用独立变量名,避免覆盖模型类 existing_customer = ndb.Key('customer', customer_id).get() # 先确认实体存在再执行更新 if existing_customer: existing_customer.firstName = firstName existing_customer.lastName = lastName existing_customer.phone = phone existing_customer.countryCode = countryCode customer_key = existing_customer.put() else: # 处理实体不存在的业务逻辑 pass
2. 确保customer_id类型正确
如果customer_id从URL参数或表单获取的是字符串类型,需先转换为整数(匹配实体ID的类型):
# 以Django请求为例,转换参数类型 customer_id = int(request.POST.get('customer_id')) existing_customer = ndb.Key('customer', customer_id).get()
3. 更新Cloud Ndb版本
确保使用最新版本的Cloud Ndb,规避旧版本的已知bug:
pip install google-cloud-ndb --upgrade
4. 确认请求上下文初始化
在GAE的请求处理函数中,确保Cloud Ndb上下文正确初始化。如果使用Django,可在视图中添加上下文管理:
from google.cloud import ndb def edit_customer(request, customer_id): # 初始化ndb上下文 with ndb.Client().context(): existing_customer = ndb.Key('customer', int(customer_id)).get() # 后续更新逻辑...
内容的提问来源于stack exchange,提问作者Nazih AIT BENSAID
相关产品推荐
相关产品推荐

