CouchDB On-the-fly attachments through command-line
Asked Answered
A

3

9

PROBLEM

I want to be able to attach one/multiple attachment(s) as the document is created, through the command-line (see below). I can only get this to work in Futon (Couchbase), but only after a document has already been created.

I have tried the following:

curl -X PUT 'http://username:password@localhost:5984/client_info'

curl -X POST 'http://username:password@localhost:5984/client_info' -H 'Content-Type: application/json' -d '{"client_type": "Private", "client_name": "John Doe","client_email": "[email protected]","client_city": "Toronto","created_at": "2011-09-06 12:45:03","expires_at": "2012-01-01 00:00:00", "_attachments": {
   "test01.jpg": {
       "content_type": "image/jpeg",
       "length": 30189          
    }
  }
}'

This only results in the following error:

{"error":"unknown_error","reason":"function_clause"}

Thanks

Artificiality answered 20/10, 2011 at 10:12 Comment(0)
P
16

You must upload your attachment in a separate step, containing the actual attachment file in the request body. So first create your regular document, then issue another request where you upload the file. Here is an example on how to upload an attachment using curl (http://guide.couchdb.org/draft/api.html#attachments): curl -v -X PUT http://127.0.0.1:5984/albums/6e1295ed6c29495e54cc05947f18c8af/artwork.jpg?rev=2-2739352689 --data-binary @artwork.jpg -H "Content-Type: image/jpg"

And here is the official API for attachments: http://wiki.apache.org/couchdb/HTTP_Document_API#Standalone_Attachments

Pederson answered 20/10, 2011 at 10:47 Comment(3)
So I first need to create the document, get a _rev and then use PUT to finally attach an image? Why isn't it possible to do this simultaneously? What if the information I want to input is from a registration form, where the user has the ability to upload one or more pictures? How would I go about doing this?Artificiality
If you're looking for a highly scalable storage for binary objects that write into something like a bucket concurrently, CouchDB may not be your first choice. There are still several workarounds for your problem: Store local copies of the uploaded images locally and queue them for sequential upload. Alternatively, store each image in a distinct document (allows parallel upload), and only add the _ids of the image documents in your user document. To do everything in one request: Base64-encode your images and include them to your document JSON (ugly in terms of performance).Pederson
If you get an error: "no matches found: ..." put the url into the quotes: curl -v -X PUT '127.0.0.1:5984/albums/6e1295ed6c29495e54cc05947f18c8af/…' --data-binary @artwork.jpg -H "Content-Type: image/jpg"Leda
V
6

This works for me, and seems a little simpler. The first one has to be when creating the doc, if you don't add a rev. My examples uses database "test1".

$ curl -H "Content-Type: image/jpeg" -X PUT --data-binary @test01.jpg 'http://username:password@localhost:5984/test1/client_info/test01.jpg'

{"ok":true,"id":"client_info","rev":"1-8584b6af9d0c3347ba08202697f09952"}

$ curl -H "Content-Type: image/jpeg" -X PUT --data-binary @test02.jpg 'http://username:password@localhost:5984/test1/client_info/test02.jpg?rev=1-8584b6af9d0c3347ba08202697f09952'

{"ok":true,"id":"client_info","rev":"2-623b94aba30944d6744f5c11cf03fc10"}
Valene answered 12/12, 2012 at 21:25 Comment(0)
C
2

Here is a way to upload an attachment in the same request as the creation of the document.

curl -X POST 'http://user:pass@localhost:5984/client_stuff' -H 'Content-Type: application/json' -d '{"stuff": "stuff", "_attachments": {
   "empty.gif": {
       "content_type": "image/gif",
       "data": "'$(openssl base64 < file.gif)'"
    }
  }
}'

Depending on your use case, the Base64-encoding may not be so bad.

More info: http://wiki.apache.org/couchdb/HTTP_Document_API#Inline_Attachments

Crashing answered 7/9, 2012 at 16:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.