2013-08-08 62 views
5

Tôi đang cố gắng để put_item kiểm tra xem có mục nào có cùng HashKey trước khi thực sự thêm mục mới hay không.Boto DynamoDB2 có điều kiện put_item

Theo tài liệu boto DynamoDB2, có thể thực hiện điều đó với "Đặt điều kiện".

Tôi đã thử lệnh sau nhưng không may mắn.

connection.put_item('table',item={'locationId':'a1', 'timestamp': time.time()}, expected={'locationID':False}) 

Thông báo lỗi như sau.

boto.exception.JSONResponseError: JSONResponseError: 400 Bad Request 
{u'Message': u'Expected null', u'__type': u'com.amazon.coral.service#SerializationException'} 

Có ai có điều kiện với DynamoDBv2 không?

Nhờ tất cả trước.

+0

Bạn có thể yêu cầu DynamoDB chỉ lưu trữ mục nếu chưa có một mục có cùng khóa chính nhưng trong trường hợp đó mệnh đề '' expected'' sẽ phải tham chiếu đến khóa chính đó, chứ không phải '' False' '. – garnaat

+0

@garnaat, Cảm ơn bạn đã bình luận. Tôi nghĩ rằng có thể có nhiều lỗi. Tôi đã thử lệnh ngay cả khi không có phần 'mong đợi' và vẫn nhận được cùng một lỗi - 'boto.exception.JSONResponseError: JSONResponseError: 400 Yêu cầu Không hợp lệ {u'Message': u'Expected null ', u' __ type ': u'com .amazon.coral.service # SerializationException '} '. Tôi tự hỏi nếu có bất kỳ ví dụ 'put_item()' có điều kiện nào mà tôi có thể xem xét ... Tôi đã thử tìm kiếm trên google nhưng không may mắn. – nicklee

+0

@garnaat bạn có bất kỳ mã ví dụ nào hoạt động với DynamodB v2 không? – nicklee

Trả lời

6

Bạn cần phải viết như thế này để cú pháp hoạt động. Rất tệ là nó không được ghi chép ở bất cứ đâu. Tôi chỉ gặp vấn đề tương tự và phải thử 50 thứ khác nhau trong khi tìm hiểu tài liệu Java SDK để nó hoạt động. Lưu ý rằng bạn cần cung cấp giá trị nếu bạn muốn đi với 'Exists': True thay vì False.

connection.put_item(
    'table', 
    item={ 
     'locationId':{'S': 'a1'}, 
     'timestamp': {'N': str(time.time()) 
    }, 
    expected={ 
     'locationID': {'Exists': False} 
    } 
    #expected={ 
    # 'locationID': {'Exists': True, 'Value': {'N': '0'}} 
    #} 
) 

Hy vọng điều đó sẽ hữu ích!

Edit: the question that helped me with the syntax enough to make it workcode in the boto integration tests

+0

Tôi đã cố gắng sử dụng mã bạn cung cấp nhưng vẫn có "TypeError: put_item() đã nhận được một đối số từ khóa không mong muốn 'hy vọng'". Không có mệnh đề mong đợi, nó hoạt động (nhập mục và trả về true). – nicklee

+0

Nó phải là "mong đợi", không phải "mong đợi" :) – moodh

+0

xin lỗi, tôi đã sử dụng thông báo lỗi sai. Ngay cả với 'dự kiến', tôi nhận được cùng một lỗi như sau ... Traceback (cuộc gọi gần đây nhất): Tệp "", dòng 6, trong TypeError: put_item() có đối số từ khóa không mong muốn 'expected' – nicklee

0

Lưu ý rằng tham số expected của put_item tại deprecated là:

Parameters: expected (map)

There is a newer parameter available. Use ConditionExpression instead.

Sử dụng condition_expression thay vì:

connection.put_item(
    'table', 
    item={ 
     'locationId': {'S': 'a1'}, 
     'timestamp': {'S': str(time.time())} 
    }, 
    condition_expression='attribute_exists(locationId)' 
) 

Nó cũng có thể biểu hiện chuỗi và sử dụng các tham số có tên, ví dụ:

connection.put_item(
    'table', 
    item={ 
     'locationId': {'S': 'a1'}, 
     'timestamp': {'S': str(time.time())} 
    }, 
    condition_expression=(
     'attribute_exists(locationId) AND ' 
     'NOT attribute_type(locationId, :expected_type)' 
    ), 
    expression_attribute_values={ 
     ':expected_type': {'S': 'NULL'} # String parameter of value 'NULL' 
    } 
) 

See Performing Conditional Writes with Condition Expressions for more details.