Mock more of the Glue Data Catalog APIs
This adds some of the missing Get/Update/Create APIs relating to the Glue data catalog -- but not yet all of them, and none of the Batch* API calls.
This commit is contained in:
parent
dfa7935e13
commit
5783d66206
6 changed files with 673 additions and 61 deletions
|
|
@ -1,8 +1,19 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import time
|
||||
|
||||
from moto.core import BaseBackend, BaseModel
|
||||
from moto.compat import OrderedDict
|
||||
from.exceptions import DatabaseAlreadyExistsException, TableAlreadyExistsException
|
||||
from.exceptions import (
|
||||
JsonRESTError,
|
||||
DatabaseAlreadyExistsException,
|
||||
DatabaseNotFoundException,
|
||||
TableAlreadyExistsException,
|
||||
TableNotFoundException,
|
||||
PartitionAlreadyExistsException,
|
||||
PartitionNotFoundException,
|
||||
VersionNotFoundException,
|
||||
)
|
||||
|
||||
|
||||
class GlueBackend(BaseBackend):
|
||||
|
|
@ -19,7 +30,10 @@ class GlueBackend(BaseBackend):
|
|||
return database
|
||||
|
||||
def get_database(self, database_name):
|
||||
return self.databases[database_name]
|
||||
try:
|
||||
return self.databases[database_name]
|
||||
except KeyError:
|
||||
raise DatabaseNotFoundException(database_name)
|
||||
|
||||
def create_table(self, database_name, table_name, table_input):
|
||||
database = self.get_database(database_name)
|
||||
|
|
@ -33,7 +47,10 @@ class GlueBackend(BaseBackend):
|
|||
|
||||
def get_table(self, database_name, table_name):
|
||||
database = self.get_database(database_name)
|
||||
return database.tables[table_name]
|
||||
try:
|
||||
return database.tables[table_name]
|
||||
except KeyError:
|
||||
raise TableNotFoundException(table_name)
|
||||
|
||||
def get_tables(self, database_name):
|
||||
database = self.get_database(database_name)
|
||||
|
|
@ -52,9 +69,84 @@ class FakeTable(BaseModel):
|
|||
def __init__(self, database_name, table_name, table_input):
|
||||
self.database_name = database_name
|
||||
self.name = table_name
|
||||
self.table_input = table_input
|
||||
self.storage_descriptor = self.table_input.get('StorageDescriptor', {})
|
||||
self.partition_keys = self.table_input.get('PartitionKeys', [])
|
||||
self.partitions = OrderedDict()
|
||||
self.versions = []
|
||||
self.update(table_input)
|
||||
|
||||
def update(self, table_input):
|
||||
self.versions.append(table_input)
|
||||
|
||||
def get_version(self, ver):
|
||||
try:
|
||||
if not isinstance(ver, int):
|
||||
# "1" goes to [0]
|
||||
ver = int(ver) - 1
|
||||
except ValueError as e:
|
||||
raise JsonRESTError("InvalidInputException", str(e))
|
||||
|
||||
try:
|
||||
return self.versions[ver]
|
||||
except IndexError:
|
||||
raise VersionNotFoundException()
|
||||
|
||||
def as_dict(self, version=-1):
|
||||
obj = {
|
||||
'DatabaseName': self.database_name,
|
||||
'Name': self.name,
|
||||
}
|
||||
obj.update(self.get_version(version))
|
||||
return obj
|
||||
|
||||
def create_partition(self, partiton_input):
|
||||
partition = FakePartition(self.database_name, self.name, partiton_input)
|
||||
key = str(partition.values)
|
||||
if key in self.partitions:
|
||||
raise PartitionAlreadyExistsException()
|
||||
self.partitions[str(partition.values)] = partition
|
||||
|
||||
def get_partitions(self):
|
||||
return [p for str_part_values, p in self.partitions.items()]
|
||||
|
||||
def get_partition(self, values):
|
||||
try:
|
||||
return self.partitions[str(values)]
|
||||
except KeyError:
|
||||
raise PartitionNotFoundException()
|
||||
|
||||
def update_partition(self, old_values, partiton_input):
|
||||
partition = FakePartition(self.database_name, self.name, partiton_input)
|
||||
key = str(partition.values)
|
||||
if old_values == partiton_input['Values']:
|
||||
# Altering a partition in place. Don't remove it so the order of
|
||||
# returned partitions doesn't change
|
||||
if key not in self.partitions:
|
||||
raise PartitionNotFoundException()
|
||||
else:
|
||||
removed = self.partitions.pop(str(old_values), None)
|
||||
if removed is None:
|
||||
raise PartitionNotFoundException()
|
||||
if key in self.partitions:
|
||||
# Trying to update to overwrite a partition that exists
|
||||
raise PartitionAlreadyExistsException()
|
||||
self.partitions[key] = partition
|
||||
|
||||
|
||||
class FakePartition(BaseModel):
|
||||
def __init__(self, database_name, table_name, partiton_input):
|
||||
self.creation_time = time.time()
|
||||
self.database_name = database_name
|
||||
self.table_name = table_name
|
||||
self.partition_input = partiton_input
|
||||
self.values = self.partition_input.get('Values', [])
|
||||
|
||||
def as_dict(self):
|
||||
obj = {
|
||||
'DatabaseName': self.database_name,
|
||||
'TableName': self.table_name,
|
||||
'CreationTime': self.creation_time,
|
||||
}
|
||||
obj.update(self.partition_input)
|
||||
return obj
|
||||
|
||||
|
||||
glue_backend = GlueBackend()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue