简体   繁体   中英

Cosmos DB - Delete Document with Python

In this SO question I had learnt that I cannot delete a Cosmos DB document using SQL.

Using Python, I believe I need the DeleteDocument() method. This is how I'm getting the document ID's that are required (I believe) to then call the DeleteDocument() method.

# set up the client
client = document_client.DocumentClient()

# use a SQL based query to get a bunch of documents
query = { 'query': 'SELECT * FROM server s' }
result_iterable = client.QueryDocuments('dbs/DB/colls/coll', query, options)

results = list(result_iterable);

for x in range(0, len (results)):
    docID = results[x]['id']

Now, at this stage I want to call DeleteDocument() . The inputs into which are document_link and options .

I can define document_link as something like

document_link = 'dbs/DB/colls/coll/docs/'+docID

And successfully call ReadAttachments() for example, which has the same inputs as DeleteDocument() .

When I do however, I get an error...

The partition key supplied in x-ms-partitionkey header has fewer
components than defined in the the collection

...and now I'm totally lost

UPDATE

Following on from Jay's help, I believe I'm missing the partitonKey element in the options.

In this example, I've created a testing database, it looks like this来自我的 Azure 帐户的屏幕截图

So I think my partition key is /testPART

When I include the partitionKey in the options however, no results are returned, (and so print len(results) outputs 0).

Removing partitionKey means that results are returned, but the delete attempt fails as before.

# Query them in SQL
query = { 'query': 'SELECT * FROM c' }

options = {}
options['enableCrossPartitionQuery'] = True
options['maxItemCount'] = 2
options['partitionKey'] = '/testPART'
result_iterable = client.QueryDocuments('dbs/testDB/colls/testCOLL', query, options)
results = list(result_iterable)

# should be > 0
print len(results)

for x in range(0, len (results)):
    docID = results[x]['id']
    print docID
    client.DeleteDocument('dbs/testDB/colls/testCOLL/docs/'+docID, options=options)
    print 'deleted', docID

According to your description, I tried to use pydocument module to delete document in my azure document db and it works for me.

Here is my code:

import pydocumentdb;
import pydocumentdb.document_client as document_client

config = {
    'ENDPOINT': 'Your url',
    'MASTERKEY': 'Your master key',
    'DOCUMENTDB_DATABASE': 'familydb',
    'DOCUMENTDB_COLLECTION': 'familycoll'
};

# Initialize the Python DocumentDB client
client = document_client.DocumentClient(config['ENDPOINT'], {'masterKey': config['MASTERKEY']})

# use a SQL based query to get a bunch of documents
query = { 'query': 'SELECT * FROM server s' }

options = {}
options['enableCrossPartitionQuery'] = True
options['maxItemCount'] = 2

result_iterable = client.QueryDocuments('dbs/familydb/colls/familycoll', query, options)

results = list(result_iterable);

print(results)

client.DeleteDocument('dbs/familydb/colls/familycoll/docs/id1',options)

print 'delete success'

Console Result:

[{u'_self': u'dbs/hitPAA==/colls/hitPAL3OLgA=/docs/hitPAL3OLgABAAAAAAAAAA==/', u'myJsonArray': [{u'subId': u'sub1', u'val': u'value1'}, {u'subId': u'sub2', u'val': u'value2'}], u'_ts': 1507687788, u'_rid': u'hitPAL3OLgABAAAAAAAAAA==', u'_attachments': u'attachments/', u'_etag': u'"00002100-0000-0000-0000-59dd7d6c0000"', u'id': u'id1'}, {u'_self': u'dbs/hitPAA==/colls/hitPAL3OLgA=/docs/hitPAL3OLgACAAAAAAAAAA==/', u'myJsonArray': [{u'subId': u'sub3', u'val': u'value3'}, {u'subId': u'sub4', u'val': u'value4'}], u'_ts': 1507687809, u'_rid': u'hitPAL3OLgACAAAAAAAAAA==', u'_attachments': u'attachments/', u'_etag': u'"00002200-0000-0000-0000-59dd7d810000"', u'id': u'id2'}]
delete success

Please notice that you need to set the enableCrossPartitionQuery property to True in options if your documents are cross-partitioned .

Must be set to true for any query that requires to be executed across more than one partition. This is an explicit flag to enable you to make conscious performance tradeoffs during development time.

You could find above description from here .


Update Answer:

I think you misunderstand the meaning of partitionkey property in the options[] .

For example , my container is created like this:

在此处输入图片说明

My documents as below :

{
    "id": "1",
    "name": "jay"
}

{
    "id": "2",
    "name": "jay2"
}

My partitionkey is 'name' , so here I have two paritions : 'jay' and 'jay1' .

So, here you should set the partitionkey property to 'jay' or 'jay2',not 'name'.

Please modify your code as below:

 options = {}
    options['enableCrossPartitionQuery'] = True
    options['maxItemCount'] = 2
    options['partitionKey'] = 'jay' (please change here in your code)

    result_iterable = client.QueryDocuments('dbs/db/colls/testcoll', query, options)
    results = list(result_iterable);

    print(results)

Hope it helps you.

Using the azure.cosmos library:

install and import azure cosmos package:

from azure.cosmos import exceptions, CosmosClient, PartitionKey

define delete items function - in this case using the partition key in query:

def deleteItems(deviceid):
    client = CosmosClient(config.cosmos.endpoint, config.cosmos.primarykey)

    # Create a database if not exists
    database = client.create_database_if_not_exists(id=azure-cosmos-db-name)

    # Create a container
    # Using a good partition key improves the performance of database operations.
    container = database.create_container_if_not_exists(id=container-name, partition_key=PartitionKey(path='/your-pattition-path'), offer_throughput=400)

    #fetch items
    query = f"SELECT * FROM c WHERE c.device.deviceid IN ('{deviceid}')"
    items = list(container.query_items(query=query, enable_cross_partition_query=False))
    for item in items:
        container.delete_item(item, 'partition-key')

usage:

deviceid=10
deleteItems(items)

github full example here: https://github.com/eladtpro/python-iothub-cosmos

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM