我正在使用 PyMongo 和 PyMODM 来处理一个相当简单的文档结构。
这就是我的模型的样子:
class User(MongoModel):
subscriber_uid: fields.CharField = fields.CharField(required=True)
interface: fields.CharField = fields.CharField(required=True)
...other fields...
class Meta:
"""Defines MongoDB options for this model"""
cascade = True # currently nothing to cascade deletes against
indexes = [
IndexModel(
keys=[('subscriber_uid', pymongo.ASCENDING),
('interface', pymongo.ASCENDING)],
unique=True,
),
]
我的单元测试看起来像这样,注意 DB 是一个包装实际 PyMongo 命令的 API。例如:put_user
包装user.save()
一些异常处理逻辑,而read_user
包装User.objects.get()
.
...
user = User(**TEST_USER)
user.interface = '2/2/2/2'
user.subscriber_uid = 'some other suid'
DB.put_user(user)
user_from_db = DB.read_user(subscriber_uid=user.subscriber_uid,
interface=user.interface)
assert user_from_db.interface == user.interface
assert user_from_db.subscriber_uid == user.subscriber_uid
# attempt to create a new record with a non-unique suid+iface pair
# ie: ensure this updates instead of creates
user = User(**TEST_USER)
user.someotherattr = 1023
DB.put_user(user)
user_from_db: User = DB.read_user(subscriber_uid=user.subscriber_uid,
interface=user.interface)
assert user_from_db.seed_index == user.seed_index
...
当我运行这个测试时,read_user()
/User.objects.get()
调用失败并MultipleObjectsReturned
返回对象错误,我可以确认有两条记录具有相同的interface
和subscriber_uid
值。
从我在其他 StackOverflow答案和评论中看到的情况来看,上面的复合唯一索引应该可以防止这种情况发生。
每次测试运行时都会删除数据库,因此问题不在于陈旧的数据挥之不去。我误解了复合指数吗?