【问题标题】:How to programmatically determine if ndb property is multivalue如何以编程方式确定 ndb 属性是否为多值
【发布时间】:2026-01-10 17:50:01
【问题描述】:

我正在将应用程序从 Datastore 转换为 ndb,但在 xml 导入例程中遇到了问题。问题是我无法以编程方式确定 ndb.model 类的属性是否为多值属性。

我怀疑这是由于缺乏基本的 Python 技能,因为到目前为止我提出的代码表明该值是“可见的”。因此我无法抓住它。请帮忙。

from google.appengine.ext import ndb

class House(ndb.Model):
  name = ndb.StringProperty()   
  rooms = ndb.StringProperty(repeated=True) 

print 'Properties:'
for p in House._properties:
  print getattr(House,p)

print '\nRepeated:'
for p in House._properties:
  print getattr(getattr(House,p),'repeated',None)

这会导致以下结果:

Properties:
StringProperty('rooms', repeated=True)
StringProperty('name')

Repeated:
None
None

【问题讨论】:

  • 好的,我查看了源代码,在 Property 类中有一个名为 ´_´repeated 的属性可以访问。它有效,但我有预感“'_'”意味着它不适合外部访问。

标签: python google-app-engine app-engine-ndb


【解决方案1】:

其实下划线前缀的选项官方API。这是他们没有记录的错误,我会修复它。我在这里解释了一点:http://code.google.com/p/appengine-ndb-experiment/issues/detail?id=187

特别是,要获取模型的属性,您应该使用 House._properties,而不是 Nick 建议的代码。 (事实上​​,__dict__ 在未来的 NDB 版本中可能会被替换为插槽。)

【讨论】:

  • 谢谢罗森先生的澄清。
【解决方案2】:

NDB 目前不提供任何选项来内省创建的模型;你绝对应该file a bug 关于这个。与此同时,深入研究对象的内部是解决问题的唯一方法。请注意,这是非常脆弱的,因为内部实现细节可以而且随时会改变。

你可以获得这样的属性列表:

properties = [(k, v) for k, v in House.__dict__.items() if isinstance(v, ndb.Property)]

您可以通过访问实例上的 _repeated 内部属性来确定属性是否重复 - 但请参阅我上面的免责声明,了解为什么这可能是一个坏主意:

House.rooms._repeated

getattr(House, 'rooms')._repeated

【讨论】:

  • 谢谢尼克。我已按照建议将其添加为issue