0

I'm trying to rename a ArangoDB collection using pyArango. This is what I have so far:

connection = pyArango.Connection('http://random-address', username='random-username', password='random-password')
test_db = Database(connection, 'test-db')
collection = test_db["new"]
collection.action("PUT", "rename", name="newname")

The code fails in line 4:

{'error': True, 'code': 400, 'errorNum': 1208, 'errorMessage': 'name must be non-empty'}

I'm probably using the action method incorrectly but the documentation does not provide any examples. Anybody got an idea?

Stanko
  • 4,275
  • 3
  • 23
  • 51

2 Answers2

0

A JSON object {"name": "newname"} needs to be passed as request body. The new name can not be passed as URL path parameter. The problem is the implementation of collection.action():

def action(self, method, action, **params) :
    "a generic fct for interacting everything that doesn't have an assigned fct"
    fct = getattr(self.connection.session, method.lower())
    r = fct(self.URL + "/" + action, params = params)
    return r.json()

The keyword arguments end up as dict called params. This object is passed to the request function fct() as named parameter params. This parameter receives the dict and converts it to URL path parameters, e.g. ?name=newname which is not supported by the HTTP API of the server.

There is unfortunately no way to pass a payload via action(). You can write some custom code however:

from pyArango.connection import *
connection = Connection('http://localhost:8529', username='root', password='')

try:
    connection.createDatabase('test-db')
except CreationError:
    pass
test_db = Database(connection, 'test-db')

try:
    test_db.createCollection(name='new')
except CreationError:
    pass
collection = test_db['new']

r = connection.session.put(collection.URL + '/rename', data='{"name":"newname"}')
print(r.text)
collection = test_db['newname']

You can also use a dict for the payload and transform it to JSON if you want:

import json
...put(..., data=json.dumps({"name": "newname"}))
CodeManX
  • 11,159
  • 5
  • 49
  • 70
0

I've fixed it like this:

def rename_collection(arango_uri, username, password, database, collection, new_name):
    url = '{}/_db/{}/_api/collection/{}/rename'.format(arango_uri, database, collection)
    params = {"name": new_name}
    response = requests.put(url, data=json.dumps(params), auth=HTTPBasicAuth(username, password))
    return response
Stanko
  • 4,275
  • 3
  • 23
  • 51