metricq / aiocouch

🛋 An asynchronous client library for CouchDB 2.x and 3.x
https://aiocouch.readthedocs.io/en/latest/
BSD 3-Clause "New" or "Revised" License
29 stars 10 forks source link

POST /db/_bulk_docs without fetching documents first #25

Closed adrienverge closed 4 years ago

adrienverge commented 4 years ago

This follows https://github.com/metricq/aiocouch/pull/23#discussion_r400097633.

Sometimes it's needed to write many documents that don't exist yet, in one operation. Currently, it can be done by passing ids=[] and writing to _docs:

# Create 100 documents that don't exist yet:
db = Database(couch, 'db')
async with db.update_docs([]) as docs:
    for i in range(100):
        doc = Document(db, 'id-%d' % i)
        doc.update({'number': i})
        docs._docs.append(doc)

But this code makes a first (useless) HTTP call to CouchDB to fetch zero documents, then a second (useful) one to write new documents. I wish I could simply do:

async with db.update_docs() as docs:  # don't fetch anything, I want write-only
    for i in range(100):
        doc = Document(db, 'id-%d' % i)
        doc.update({'number': i})
        docs.append(doc)  # don't use a private attribute _docs

Of course this could be done using the BulkOperation class directly, but I don't think this is the intended usage.

bmario commented 4 years ago

I think the missing piece is create_docs(). I created the first idea for an interface in this branch. I'm not to keen on the name of the BulkStoreOperation.create() method, though.

adrienverge commented 4 years ago

Hey @bmario, I've looked at your branch and it looks good. In my opinion the name of BulkStoreOperation.create() is okay: simple and explicit (I don't have a better proposal).

What would be even better (cf. #24) is to create a new doc with:

async with database.create_docs() as docs:
    docs.create("foo", init={"counter": 42})
    # foo = docs.create("foo")
    # foo["counter"] = 42