Merge pull request #1750 from TheDooner64/glue-data-catalog
Scaffolding for AWS Glue Data Catalog
This commit is contained in:
commit
42d486f9b0
15 changed files with 356 additions and 2 deletions
|
|
@ -24,6 +24,7 @@ from .elbv2 import mock_elbv2 # flake8: noqa
|
|||
from .emr import mock_emr, mock_emr_deprecated # flake8: noqa
|
||||
from .events import mock_events # flake8: noqa
|
||||
from .glacier import mock_glacier, mock_glacier_deprecated # flake8: noqa
|
||||
from .glue import mock_glue # flake8: noqa
|
||||
from .iam import mock_iam, mock_iam_deprecated # flake8: noqa
|
||||
from .kinesis import mock_kinesis, mock_kinesis_deprecated # flake8: noqa
|
||||
from .kms import mock_kms, mock_kms_deprecated # flake8: noqa
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ from moto.elbv2 import elbv2_backends
|
|||
from moto.emr import emr_backends
|
||||
from moto.events import events_backends
|
||||
from moto.glacier import glacier_backends
|
||||
from moto.glue import glue_backends
|
||||
from moto.iam import iam_backends
|
||||
from moto.instance_metadata import instance_metadata_backends
|
||||
from moto.kinesis import kinesis_backends
|
||||
|
|
@ -65,6 +66,7 @@ BACKENDS = {
|
|||
'events': events_backends,
|
||||
'emr': emr_backends,
|
||||
'glacier': glacier_backends,
|
||||
'glue': glue_backends,
|
||||
'iam': iam_backends,
|
||||
'moto_api': moto_api_backends,
|
||||
'instance_metadata': instance_metadata_backends,
|
||||
|
|
|
|||
5
moto/glue/__init__.py
Normal file
5
moto/glue/__init__.py
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
from __future__ import unicode_literals
|
||||
from .models import glue_backend
|
||||
|
||||
glue_backends = {"global": glue_backend}
|
||||
mock_glue = glue_backend.decorator
|
||||
24
moto/glue/exceptions.py
Normal file
24
moto/glue/exceptions.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
from __future__ import unicode_literals
|
||||
from moto.core.exceptions import JsonRESTError
|
||||
|
||||
|
||||
class GlueClientError(JsonRESTError):
|
||||
code = 400
|
||||
|
||||
|
||||
class DatabaseAlreadyExistsException(GlueClientError):
|
||||
def __init__(self):
|
||||
self.code = 400
|
||||
super(DatabaseAlreadyExistsException, self).__init__(
|
||||
'DatabaseAlreadyExistsException',
|
||||
'Database already exists.'
|
||||
)
|
||||
|
||||
|
||||
class TableAlreadyExistsException(GlueClientError):
|
||||
def __init__(self):
|
||||
self.code = 400
|
||||
super(TableAlreadyExistsException, self).__init__(
|
||||
'TableAlreadyExistsException',
|
||||
'Table already exists.'
|
||||
)
|
||||
60
moto/glue/models.py
Normal file
60
moto/glue/models.py
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from moto.core import BaseBackend, BaseModel
|
||||
from moto.compat import OrderedDict
|
||||
from.exceptions import DatabaseAlreadyExistsException, TableAlreadyExistsException
|
||||
|
||||
|
||||
class GlueBackend(BaseBackend):
|
||||
|
||||
def __init__(self):
|
||||
self.databases = OrderedDict()
|
||||
|
||||
def create_database(self, database_name):
|
||||
if database_name in self.databases:
|
||||
raise DatabaseAlreadyExistsException()
|
||||
|
||||
database = FakeDatabase(database_name)
|
||||
self.databases[database_name] = database
|
||||
return database
|
||||
|
||||
def get_database(self, database_name):
|
||||
return self.databases[database_name]
|
||||
|
||||
def create_table(self, database_name, table_name, table_input):
|
||||
database = self.get_database(database_name)
|
||||
|
||||
if table_name in database.tables:
|
||||
raise TableAlreadyExistsException()
|
||||
|
||||
table = FakeTable(database_name, table_name, table_input)
|
||||
database.tables[table_name] = table
|
||||
return table
|
||||
|
||||
def get_table(self, database_name, table_name):
|
||||
database = self.get_database(database_name)
|
||||
return database.tables[table_name]
|
||||
|
||||
def get_tables(self, database_name):
|
||||
database = self.get_database(database_name)
|
||||
return [table for table_name, table in database.tables.items()]
|
||||
|
||||
|
||||
class FakeDatabase(BaseModel):
|
||||
|
||||
def __init__(self, database_name):
|
||||
self.name = database_name
|
||||
self.tables = OrderedDict()
|
||||
|
||||
|
||||
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', [])
|
||||
|
||||
|
||||
glue_backend = GlueBackend()
|
||||
63
moto/glue/responses.py
Normal file
63
moto/glue/responses.py
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
|
||||
from moto.core.responses import BaseResponse
|
||||
from .models import glue_backend
|
||||
|
||||
|
||||
class GlueResponse(BaseResponse):
|
||||
|
||||
@property
|
||||
def glue_backend(self):
|
||||
return glue_backend
|
||||
|
||||
@property
|
||||
def parameters(self):
|
||||
return json.loads(self.body)
|
||||
|
||||
def create_database(self):
|
||||
database_name = self.parameters['DatabaseInput']['Name']
|
||||
self.glue_backend.create_database(database_name)
|
||||
return ""
|
||||
|
||||
def get_database(self):
|
||||
database_name = self.parameters.get('Name')
|
||||
database = self.glue_backend.get_database(database_name)
|
||||
return json.dumps({'Database': {'Name': database.name}})
|
||||
|
||||
def create_table(self):
|
||||
database_name = self.parameters.get('DatabaseName')
|
||||
table_input = self.parameters.get('TableInput')
|
||||
table_name = table_input.get('Name')
|
||||
self.glue_backend.create_table(database_name, table_name, table_input)
|
||||
return ""
|
||||
|
||||
def get_table(self):
|
||||
database_name = self.parameters.get('DatabaseName')
|
||||
table_name = self.parameters.get('Name')
|
||||
table = self.glue_backend.get_table(database_name, table_name)
|
||||
return json.dumps({
|
||||
'Table': {
|
||||
'DatabaseName': table.database_name,
|
||||
'Name': table.name,
|
||||
'PartitionKeys': table.partition_keys,
|
||||
'StorageDescriptor': table.storage_descriptor
|
||||
}
|
||||
})
|
||||
|
||||
def get_tables(self):
|
||||
database_name = self.parameters.get('DatabaseName')
|
||||
tables = self.glue_backend.get_tables(database_name)
|
||||
return json.dumps(
|
||||
{
|
||||
'TableList': [
|
||||
{
|
||||
'DatabaseName': table.database_name,
|
||||
'Name': table.name,
|
||||
'PartitionKeys': table.partition_keys,
|
||||
'StorageDescriptor': table.storage_descriptor
|
||||
} for table in tables
|
||||
]
|
||||
}
|
||||
)
|
||||
11
moto/glue/urls.py
Normal file
11
moto/glue/urls.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from .responses import GlueResponse
|
||||
|
||||
url_bases = [
|
||||
"https?://glue(.*).amazonaws.com"
|
||||
]
|
||||
|
||||
url_paths = {
|
||||
'{0}/$': GlueResponse.dispatch
|
||||
}
|
||||
1
moto/glue/utils.py
Normal file
1
moto/glue/utils.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
from __future__ import unicode_literals
|
||||
Loading…
Add table
Add a link
Reference in a new issue