2018-07-10 17:50:47 +00:00
|
|
|
from __future__ import unicode_literals
|
|
|
|
|
|
|
|
import sure # noqa
|
2018-10-02 16:25:14 +00:00
|
|
|
import re
|
2018-07-11 15:39:40 +00:00
|
|
|
from nose.tools import assert_raises
|
2018-07-10 17:50:47 +00:00
|
|
|
import boto3
|
2018-07-11 15:39:40 +00:00
|
|
|
from botocore.client import ClientError
|
2018-07-10 17:50:47 +00:00
|
|
|
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
from datetime import datetime
|
|
|
|
import pytz
|
|
|
|
|
2018-07-10 17:50:47 +00:00
|
|
|
from moto import mock_glue
|
2018-07-26 21:05:09 +00:00
|
|
|
from . import helpers
|
2018-07-10 17:50:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_create_database():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
2018-07-26 21:05:09 +00:00
|
|
|
helpers.create_database(client, database_name)
|
2018-07-10 17:50:47 +00:00
|
|
|
|
2018-07-26 21:05:09 +00:00
|
|
|
response = helpers.get_database(client, database_name)
|
2019-10-31 15:44:26 +00:00
|
|
|
database = response["Database"]
|
2018-07-10 17:50:47 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
database.should.equal({"Name": database_name})
|
2018-07-11 15:39:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_create_database_already_exists():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "cantcreatethisdatabasetwice"
|
2018-07-26 21:05:09 +00:00
|
|
|
helpers.create_database(client, database_name)
|
2018-07-11 15:39:40 +00:00
|
|
|
|
|
|
|
with assert_raises(ClientError) as exc:
|
2018-07-26 21:05:09 +00:00
|
|
|
helpers.create_database(client, database_name)
|
2018-07-11 15:39:40 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
exc.exception.response["Error"]["Code"].should.equal("AlreadyExistsException")
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_get_database_not_exits():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "nosuchdatabase"
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
with assert_raises(ClientError) as exc:
|
|
|
|
helpers.get_database(client, database_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
exc.exception.response["Error"]["Code"].should.equal("EntityNotFoundException")
|
|
|
|
exc.exception.response["Error"]["Message"].should.match(
|
|
|
|
"Database nosuchdatabase not found"
|
|
|
|
)
|
2018-07-26 21:05:09 +00:00
|
|
|
|
|
|
|
|
2020-04-21 18:10:39 +00:00
|
|
|
@mock_glue
|
|
|
|
def test_get_databases_empty():
|
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
response = client.get_databases()
|
|
|
|
response["DatabaseList"].should.have.length_of(0)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_get_databases_several_items():
|
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name_1, database_name_2 = "firstdatabase", "seconddatabase"
|
|
|
|
|
|
|
|
helpers.create_database(client, database_name_1)
|
|
|
|
helpers.create_database(client, database_name_2)
|
|
|
|
|
|
|
|
database_list = sorted(client.get_databases()["DatabaseList"], key=lambda x: x["Name"])
|
|
|
|
database_list.should.have.length_of(2)
|
|
|
|
database_list[0].should.equal({"Name": database_name_1})
|
|
|
|
database_list[1].should.equal({"Name": database_name_2})
|
|
|
|
|
|
|
|
|
2018-07-26 21:05:09 +00:00
|
|
|
@mock_glue
|
|
|
|
def test_create_table():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
2018-07-26 21:05:09 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
table_name = "myspecialtable"
|
2018-10-02 16:25:14 +00:00
|
|
|
table_input = helpers.create_table_input(database_name, table_name)
|
2018-07-26 21:05:09 +00:00
|
|
|
helpers.create_table(client, database_name, table_name, table_input)
|
|
|
|
|
|
|
|
response = helpers.get_table(client, database_name, table_name)
|
2019-10-31 15:44:26 +00:00
|
|
|
table = response["Table"]
|
2018-07-26 21:05:09 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
table["Name"].should.equal(table_input["Name"])
|
|
|
|
table["StorageDescriptor"].should.equal(table_input["StorageDescriptor"])
|
|
|
|
table["PartitionKeys"].should.equal(table_input["PartitionKeys"])
|
2018-07-26 21:05:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_create_table_already_exists():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
2018-07-26 21:05:09 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
table_name = "cantcreatethistabletwice"
|
2018-10-02 16:25:14 +00:00
|
|
|
helpers.create_table(client, database_name, table_name)
|
2018-07-26 21:05:09 +00:00
|
|
|
|
|
|
|
with assert_raises(ClientError) as exc:
|
2018-10-02 16:25:14 +00:00
|
|
|
helpers.create_table(client, database_name, table_name)
|
2018-07-26 21:05:09 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
exc.exception.response["Error"]["Code"].should.equal("AlreadyExistsException")
|
2018-07-26 21:05:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_get_tables():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
2018-07-26 21:05:09 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
table_names = ["myfirsttable", "mysecondtable", "mythirdtable"]
|
2018-07-26 21:05:09 +00:00
|
|
|
table_inputs = {}
|
|
|
|
|
|
|
|
for table_name in table_names:
|
2018-10-02 16:25:14 +00:00
|
|
|
table_input = helpers.create_table_input(database_name, table_name)
|
2018-07-26 21:05:09 +00:00
|
|
|
table_inputs[table_name] = table_input
|
|
|
|
helpers.create_table(client, database_name, table_name, table_input)
|
|
|
|
|
|
|
|
response = helpers.get_tables(client, database_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
tables = response["TableList"]
|
2018-07-26 21:05:09 +00:00
|
|
|
|
2018-10-02 16:25:14 +00:00
|
|
|
tables.should.have.length_of(3)
|
2018-07-26 21:05:09 +00:00
|
|
|
|
|
|
|
for table in tables:
|
2019-10-31 15:44:26 +00:00
|
|
|
table_name = table["Name"]
|
|
|
|
table_name.should.equal(table_inputs[table_name]["Name"])
|
|
|
|
table["StorageDescriptor"].should.equal(
|
|
|
|
table_inputs[table_name]["StorageDescriptor"]
|
|
|
|
)
|
|
|
|
table["PartitionKeys"].should.equal(table_inputs[table_name]["PartitionKeys"])
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_get_table_versions():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
2018-10-02 16:25:14 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
table_name = "myfirsttable"
|
2018-10-02 16:25:14 +00:00
|
|
|
version_inputs = {}
|
|
|
|
|
|
|
|
table_input = helpers.create_table_input(database_name, table_name)
|
|
|
|
helpers.create_table(client, database_name, table_name, table_input)
|
|
|
|
version_inputs["1"] = table_input
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
columns = [{"Name": "country", "Type": "string"}]
|
2018-10-02 16:25:14 +00:00
|
|
|
table_input = helpers.create_table_input(database_name, table_name, columns=columns)
|
|
|
|
helpers.update_table(client, database_name, table_name, table_input)
|
|
|
|
version_inputs["2"] = table_input
|
|
|
|
|
2020-01-20 23:21:11 +00:00
|
|
|
# Updateing with an identical input should still create a new version
|
2018-10-02 16:25:14 +00:00
|
|
|
helpers.update_table(client, database_name, table_name, table_input)
|
|
|
|
version_inputs["3"] = table_input
|
|
|
|
|
|
|
|
response = helpers.get_table_versions(client, database_name, table_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
vers = response["TableVersions"]
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
vers.should.have.length_of(3)
|
2019-10-31 15:44:26 +00:00
|
|
|
vers[0]["Table"]["StorageDescriptor"]["Columns"].should.equal([])
|
|
|
|
vers[-1]["Table"]["StorageDescriptor"]["Columns"].should.equal(columns)
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
for n, ver in enumerate(vers):
|
|
|
|
n = str(n + 1)
|
2019-10-31 15:44:26 +00:00
|
|
|
ver["VersionId"].should.equal(n)
|
|
|
|
ver["Table"]["Name"].should.equal(table_name)
|
|
|
|
ver["Table"]["StorageDescriptor"].should.equal(
|
|
|
|
version_inputs[n]["StorageDescriptor"]
|
|
|
|
)
|
|
|
|
ver["Table"]["PartitionKeys"].should.equal(version_inputs[n]["PartitionKeys"])
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
response = helpers.get_table_version(client, database_name, table_name, "3")
|
2019-10-31 15:44:26 +00:00
|
|
|
ver = response["TableVersion"]
|
2018-10-02 16:25:14 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
ver["VersionId"].should.equal("3")
|
|
|
|
ver["Table"]["Name"].should.equal(table_name)
|
|
|
|
ver["Table"]["StorageDescriptor"]["Columns"].should.equal(columns)
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_get_table_version_not_found():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
2018-10-02 16:25:14 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
|
|
|
with assert_raises(ClientError) as exc:
|
2019-10-31 15:44:26 +00:00
|
|
|
helpers.get_table_version(client, database_name, "myfirsttable", "20")
|
2018-10-02 16:25:14 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
exc.exception.response["Error"]["Code"].should.equal("EntityNotFoundException")
|
|
|
|
exc.exception.response["Error"]["Message"].should.match("version", re.I)
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_get_table_version_invalid_input():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
2018-10-02 16:25:14 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
|
|
|
with assert_raises(ClientError) as exc:
|
2019-10-31 15:44:26 +00:00
|
|
|
helpers.get_table_version(client, database_name, "myfirsttable", "10not-an-int")
|
2018-10-02 16:25:14 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
exc.exception.response["Error"]["Code"].should.equal("InvalidInputException")
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_get_table_not_exits():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
2018-10-02 16:25:14 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
|
|
|
with assert_raises(ClientError) as exc:
|
2019-10-31 15:44:26 +00:00
|
|
|
helpers.get_table(client, database_name, "myfirsttable")
|
2018-10-02 16:25:14 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
exc.exception.response["Error"]["Code"].should.equal("EntityNotFoundException")
|
|
|
|
exc.exception.response["Error"]["Message"].should.match(
|
|
|
|
"Table myfirsttable not found"
|
|
|
|
)
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_get_table_when_database_not_exits():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "nosuchdatabase"
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
with assert_raises(ClientError) as exc:
|
2019-10-31 15:44:26 +00:00
|
|
|
helpers.get_table(client, database_name, "myfirsttable")
|
2018-10-02 16:25:14 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
exc.exception.response["Error"]["Code"].should.equal("EntityNotFoundException")
|
|
|
|
exc.exception.response["Error"]["Message"].should.match(
|
|
|
|
"Database nosuchdatabase not found"
|
|
|
|
)
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
|
2019-05-25 09:58:41 +00:00
|
|
|
@mock_glue
|
|
|
|
def test_delete_table():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
2019-05-25 09:58:41 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
table_name = "myspecialtable"
|
2019-05-25 09:58:41 +00:00
|
|
|
table_input = helpers.create_table_input(database_name, table_name)
|
|
|
|
helpers.create_table(client, database_name, table_name, table_input)
|
|
|
|
|
|
|
|
result = client.delete_table(DatabaseName=database_name, Name=table_name)
|
2019-10-31 15:44:26 +00:00
|
|
|
result["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
2019-05-25 09:58:41 +00:00
|
|
|
|
|
|
|
# confirm table is deleted
|
|
|
|
with assert_raises(ClientError) as exc:
|
|
|
|
helpers.get_table(client, database_name, table_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
exc.exception.response["Error"]["Code"].should.equal("EntityNotFoundException")
|
|
|
|
exc.exception.response["Error"]["Message"].should.match(
|
|
|
|
"Table myspecialtable not found"
|
|
|
|
)
|
|
|
|
|
2019-05-25 09:58:41 +00:00
|
|
|
|
2019-06-10 19:14:30 +00:00
|
|
|
@mock_glue
|
|
|
|
def test_batch_delete_table():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
2019-06-10 19:14:30 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
table_name = "myspecialtable"
|
2019-06-10 19:14:30 +00:00
|
|
|
table_input = helpers.create_table_input(database_name, table_name)
|
|
|
|
helpers.create_table(client, database_name, table_name, table_input)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
result = client.batch_delete_table(
|
|
|
|
DatabaseName=database_name, TablesToDelete=[table_name]
|
|
|
|
)
|
|
|
|
result["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
2019-06-10 19:14:30 +00:00
|
|
|
|
|
|
|
# confirm table is deleted
|
|
|
|
with assert_raises(ClientError) as exc:
|
|
|
|
helpers.get_table(client, database_name, table_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
exc.exception.response["Error"]["Code"].should.equal("EntityNotFoundException")
|
|
|
|
exc.exception.response["Error"]["Message"].should.match(
|
|
|
|
"Table myspecialtable not found"
|
|
|
|
)
|
2019-06-10 19:14:30 +00:00
|
|
|
|
2019-05-25 09:58:41 +00:00
|
|
|
|
2018-10-02 16:25:14 +00:00
|
|
|
@mock_glue
|
|
|
|
def test_get_partitions_empty():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
2018-10-02 16:25:14 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
|
|
|
response = client.get_partitions(DatabaseName=database_name, TableName=table_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["Partitions"].should.have.length_of(0)
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_create_partition():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
|
|
|
values = ["2018-10-01"]
|
2018-10-02 16:25:14 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
|
|
|
before = datetime.now(pytz.utc)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
part_input = helpers.create_partition_input(
|
|
|
|
database_name, table_name, values=values
|
|
|
|
)
|
2018-10-02 16:25:14 +00:00
|
|
|
helpers.create_partition(client, database_name, table_name, part_input)
|
|
|
|
|
|
|
|
after = datetime.now(pytz.utc)
|
|
|
|
|
|
|
|
response = client.get_partitions(DatabaseName=database_name, TableName=table_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
partitions = response["Partitions"]
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
partitions.should.have.length_of(1)
|
|
|
|
|
|
|
|
partition = partitions[0]
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
partition["TableName"].should.equal(table_name)
|
|
|
|
partition["StorageDescriptor"].should.equal(part_input["StorageDescriptor"])
|
|
|
|
partition["Values"].should.equal(values)
|
|
|
|
partition["CreationTime"].should.be.greater_than(before)
|
|
|
|
partition["CreationTime"].should.be.lower_than(after)
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_create_partition_already_exist():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
|
|
|
values = ["2018-10-01"]
|
2018-10-02 16:25:14 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
|
|
|
helpers.create_partition(client, database_name, table_name, values=values)
|
|
|
|
|
|
|
|
with assert_raises(ClientError) as exc:
|
|
|
|
helpers.create_partition(client, database_name, table_name, values=values)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
exc.exception.response["Error"]["Code"].should.equal("AlreadyExistsException")
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_get_partition_not_found():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
|
|
|
values = ["2018-10-01"]
|
2018-10-02 16:25:14 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
|
|
|
with assert_raises(ClientError) as exc:
|
|
|
|
helpers.get_partition(client, database_name, table_name, values)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
exc.exception.response["Error"]["Code"].should.equal("EntityNotFoundException")
|
|
|
|
exc.exception.response["Error"]["Message"].should.match("partition")
|
|
|
|
|
2018-10-02 16:25:14 +00:00
|
|
|
|
2019-06-07 08:28:10 +00:00
|
|
|
@mock_glue
|
|
|
|
def test_batch_create_partition():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
2019-06-07 08:28:10 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
|
|
|
before = datetime.now(pytz.utc)
|
|
|
|
|
|
|
|
partition_inputs = []
|
|
|
|
for i in range(0, 20):
|
|
|
|
values = ["2018-10-{:2}".format(i)]
|
2019-10-31 15:44:26 +00:00
|
|
|
part_input = helpers.create_partition_input(
|
|
|
|
database_name, table_name, values=values
|
|
|
|
)
|
2019-06-07 08:28:10 +00:00
|
|
|
partition_inputs.append(part_input)
|
|
|
|
|
|
|
|
client.batch_create_partition(
|
|
|
|
DatabaseName=database_name,
|
|
|
|
TableName=table_name,
|
2019-10-31 15:44:26 +00:00
|
|
|
PartitionInputList=partition_inputs,
|
2019-06-07 08:28:10 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
after = datetime.now(pytz.utc)
|
|
|
|
|
|
|
|
response = client.get_partitions(DatabaseName=database_name, TableName=table_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
partitions = response["Partitions"]
|
2019-06-07 08:28:10 +00:00
|
|
|
|
|
|
|
partitions.should.have.length_of(20)
|
|
|
|
|
|
|
|
for idx, partition in enumerate(partitions):
|
|
|
|
partition_input = partition_inputs[idx]
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
partition["TableName"].should.equal(table_name)
|
|
|
|
partition["StorageDescriptor"].should.equal(
|
|
|
|
partition_input["StorageDescriptor"]
|
|
|
|
)
|
|
|
|
partition["Values"].should.equal(partition_input["Values"])
|
|
|
|
partition["CreationTime"].should.be.greater_than(before)
|
|
|
|
partition["CreationTime"].should.be.lower_than(after)
|
2019-06-07 08:28:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_batch_create_partition_already_exist():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
|
|
|
values = ["2018-10-01"]
|
2019-06-07 08:28:10 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
|
|
|
helpers.create_partition(client, database_name, table_name, values=values)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
partition_input = helpers.create_partition_input(
|
|
|
|
database_name, table_name, values=values
|
|
|
|
)
|
2019-06-07 08:28:10 +00:00
|
|
|
|
|
|
|
response = client.batch_create_partition(
|
|
|
|
DatabaseName=database_name,
|
|
|
|
TableName=table_name,
|
2019-10-31 15:44:26 +00:00
|
|
|
PartitionInputList=[partition_input],
|
2019-06-07 08:28:10 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response.should.have.key("Errors")
|
|
|
|
response["Errors"].should.have.length_of(1)
|
|
|
|
response["Errors"][0]["PartitionValues"].should.equal(values)
|
|
|
|
response["Errors"][0]["ErrorDetail"]["ErrorCode"].should.equal(
|
|
|
|
"AlreadyExistsException"
|
|
|
|
)
|
2019-06-07 08:28:10 +00:00
|
|
|
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_get_partition():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
2018-10-02 16:25:14 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
values = [["2018-10-01"], ["2018-09-01"]]
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
helpers.create_partition(client, database_name, table_name, values=values[0])
|
|
|
|
helpers.create_partition(client, database_name, table_name, values=values[1])
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response = client.get_partition(
|
|
|
|
DatabaseName=database_name, TableName=table_name, PartitionValues=values[1]
|
|
|
|
)
|
2018-10-02 16:25:14 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
partition = response["Partition"]
|
2018-10-02 16:25:14 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
partition["TableName"].should.equal(table_name)
|
|
|
|
partition["Values"].should.equal(values[1])
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
|
2019-07-17 19:07:19 +00:00
|
|
|
@mock_glue
|
|
|
|
def test_batch_get_partition():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
2019-07-17 19:07:19 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
values = [["2018-10-01"], ["2018-09-01"]]
|
2019-07-17 19:07:19 +00:00
|
|
|
|
|
|
|
helpers.create_partition(client, database_name, table_name, values=values[0])
|
|
|
|
helpers.create_partition(client, database_name, table_name, values=values[1])
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
partitions_to_get = [{"Values": values[0]}, {"Values": values[1]}]
|
|
|
|
response = client.batch_get_partition(
|
|
|
|
DatabaseName=database_name,
|
|
|
|
TableName=table_name,
|
|
|
|
PartitionsToGet=partitions_to_get,
|
|
|
|
)
|
2019-07-17 19:07:19 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
partitions = response["Partitions"]
|
2019-07-17 19:07:19 +00:00
|
|
|
partitions.should.have.length_of(2)
|
|
|
|
|
|
|
|
partition = partitions[1]
|
2019-10-31 15:44:26 +00:00
|
|
|
partition["TableName"].should.equal(table_name)
|
|
|
|
partition["Values"].should.equal(values[1])
|
2019-07-17 19:07:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_batch_get_partition_missing_partition():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
2019-07-17 19:07:19 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
values = [["2018-10-01"], ["2018-09-01"], ["2018-08-01"]]
|
2019-07-17 19:07:19 +00:00
|
|
|
|
|
|
|
helpers.create_partition(client, database_name, table_name, values=values[0])
|
|
|
|
helpers.create_partition(client, database_name, table_name, values=values[2])
|
|
|
|
|
|
|
|
partitions_to_get = [
|
2019-10-31 15:44:26 +00:00
|
|
|
{"Values": values[0]},
|
|
|
|
{"Values": values[1]},
|
|
|
|
{"Values": values[2]},
|
2019-07-17 19:07:19 +00:00
|
|
|
]
|
2019-10-31 15:44:26 +00:00
|
|
|
response = client.batch_get_partition(
|
|
|
|
DatabaseName=database_name,
|
|
|
|
TableName=table_name,
|
|
|
|
PartitionsToGet=partitions_to_get,
|
|
|
|
)
|
2019-07-17 19:07:19 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
partitions = response["Partitions"]
|
2019-07-17 19:07:19 +00:00
|
|
|
partitions.should.have.length_of(2)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
partitions[0]["Values"].should.equal(values[0])
|
|
|
|
partitions[1]["Values"].should.equal(values[2])
|
2019-07-17 19:07:19 +00:00
|
|
|
|
|
|
|
|
2018-10-02 16:25:14 +00:00
|
|
|
@mock_glue
|
|
|
|
def test_update_partition_not_found_moving():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
|
|
|
with assert_raises(ClientError) as exc:
|
2019-10-31 15:44:26 +00:00
|
|
|
helpers.update_partition(
|
|
|
|
client,
|
|
|
|
database_name,
|
|
|
|
table_name,
|
|
|
|
old_values=["0000-00-00"],
|
|
|
|
values=["2018-10-02"],
|
|
|
|
)
|
2018-10-02 16:25:14 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
exc.exception.response["Error"]["Code"].should.equal("EntityNotFoundException")
|
|
|
|
exc.exception.response["Error"]["Message"].should.match("partition")
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_update_partition_not_found_change_in_place():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
|
|
|
values = ["2018-10-01"]
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
|
|
|
with assert_raises(ClientError) as exc:
|
2019-10-31 15:44:26 +00:00
|
|
|
helpers.update_partition(
|
|
|
|
client, database_name, table_name, old_values=values, values=values
|
|
|
|
)
|
2018-10-02 16:25:14 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
exc.exception.response["Error"]["Code"].should.equal("EntityNotFoundException")
|
|
|
|
exc.exception.response["Error"]["Message"].should.match("partition")
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_update_partition_cannot_overwrite():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
2018-10-02 16:25:14 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
values = [["2018-10-01"], ["2018-09-01"]]
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
helpers.create_partition(client, database_name, table_name, values=values[0])
|
|
|
|
helpers.create_partition(client, database_name, table_name, values=values[1])
|
|
|
|
|
|
|
|
with assert_raises(ClientError) as exc:
|
2019-10-31 15:44:26 +00:00
|
|
|
helpers.update_partition(
|
|
|
|
client, database_name, table_name, old_values=values[0], values=values[1]
|
|
|
|
)
|
2018-10-02 16:25:14 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
exc.exception.response["Error"]["Code"].should.equal("AlreadyExistsException")
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_update_partition():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
|
|
|
values = ["2018-10-01"]
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
helpers.create_partition(client, database_name, table_name, values=values)
|
|
|
|
|
|
|
|
response = helpers.update_partition(
|
|
|
|
client,
|
|
|
|
database_name,
|
|
|
|
table_name,
|
|
|
|
old_values=values,
|
|
|
|
values=values,
|
2019-10-31 15:44:26 +00:00
|
|
|
columns=[{"Name": "country", "Type": "string"}],
|
2018-10-02 16:25:14 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response = client.get_partition(
|
|
|
|
DatabaseName=database_name, TableName=table_name, PartitionValues=values
|
|
|
|
)
|
|
|
|
partition = response["Partition"]
|
2018-10-02 16:25:14 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
partition["TableName"].should.equal(table_name)
|
|
|
|
partition["StorageDescriptor"]["Columns"].should.equal(
|
|
|
|
[{"Name": "country", "Type": "string"}]
|
|
|
|
)
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_update_partition_move():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
|
|
|
values = ["2018-10-01"]
|
|
|
|
new_values = ["2018-09-01"]
|
2018-10-02 16:25:14 +00:00
|
|
|
|
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
helpers.create_partition(client, database_name, table_name, values=values)
|
|
|
|
|
|
|
|
response = helpers.update_partition(
|
|
|
|
client,
|
|
|
|
database_name,
|
|
|
|
table_name,
|
|
|
|
old_values=values,
|
|
|
|
values=new_values,
|
2019-10-31 15:44:26 +00:00
|
|
|
columns=[{"Name": "country", "Type": "string"}],
|
2018-10-02 16:25:14 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
with assert_raises(ClientError) as exc:
|
|
|
|
helpers.get_partition(client, database_name, table_name, values)
|
|
|
|
|
|
|
|
# Old partition shouldn't exist anymore
|
2019-10-31 15:44:26 +00:00
|
|
|
exc.exception.response["Error"]["Code"].should.equal("EntityNotFoundException")
|
|
|
|
|
|
|
|
response = client.get_partition(
|
|
|
|
DatabaseName=database_name, TableName=table_name, PartitionValues=new_values
|
|
|
|
)
|
|
|
|
partition = response["Partition"]
|
2018-10-02 16:25:14 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
partition["TableName"].should.equal(table_name)
|
|
|
|
partition["StorageDescriptor"]["Columns"].should.equal(
|
|
|
|
[{"Name": "country", "Type": "string"}]
|
|
|
|
)
|
2018-10-02 16:25:14 +00:00
|
|
|
|
2019-06-11 19:14:28 +00:00
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_delete_partition():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
|
|
|
values = ["2018-10-01"]
|
2019-06-11 19:14:28 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
part_input = helpers.create_partition_input(
|
|
|
|
database_name, table_name, values=values
|
|
|
|
)
|
2019-06-11 19:14:28 +00:00
|
|
|
helpers.create_partition(client, database_name, table_name, part_input)
|
|
|
|
|
|
|
|
client.delete_partition(
|
2019-10-31 15:44:26 +00:00
|
|
|
DatabaseName=database_name, TableName=table_name, PartitionValues=values
|
2019-06-11 19:14:28 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
response = client.get_partitions(DatabaseName=database_name, TableName=table_name)
|
2019-10-31 15:44:26 +00:00
|
|
|
partitions = response["Partitions"]
|
2019-06-11 19:14:28 +00:00
|
|
|
partitions.should.be.empty
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
|
2019-06-11 19:14:28 +00:00
|
|
|
@mock_glue
|
|
|
|
def test_delete_partition_bad_partition():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
|
|
|
values = ["2018-10-01"]
|
2019-06-11 19:14:28 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
|
|
|
with assert_raises(ClientError) as exc:
|
|
|
|
client.delete_partition(
|
2019-10-31 15:44:26 +00:00
|
|
|
DatabaseName=database_name, TableName=table_name, PartitionValues=values
|
2019-06-11 19:14:28 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
exc.exception.response["Error"]["Code"].should.equal("EntityNotFoundException")
|
|
|
|
|
2019-06-11 19:14:28 +00:00
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_batch_delete_partition():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
2019-06-11 19:14:28 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
|
|
|
partition_inputs = []
|
|
|
|
for i in range(0, 20):
|
|
|
|
values = ["2018-10-{:2}".format(i)]
|
2019-10-31 15:44:26 +00:00
|
|
|
part_input = helpers.create_partition_input(
|
|
|
|
database_name, table_name, values=values
|
|
|
|
)
|
2019-06-11 19:14:28 +00:00
|
|
|
partition_inputs.append(part_input)
|
|
|
|
|
|
|
|
client.batch_create_partition(
|
|
|
|
DatabaseName=database_name,
|
|
|
|
TableName=table_name,
|
2019-10-31 15:44:26 +00:00
|
|
|
PartitionInputList=partition_inputs,
|
2019-06-11 19:14:28 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
partition_values = [{"Values": p["Values"]} for p in partition_inputs]
|
|
|
|
|
|
|
|
response = client.batch_delete_partition(
|
|
|
|
DatabaseName=database_name,
|
|
|
|
TableName=table_name,
|
|
|
|
PartitionsToDelete=partition_values,
|
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response.should_not.have.key("Errors")
|
|
|
|
|
2019-06-11 19:14:28 +00:00
|
|
|
|
|
|
|
@mock_glue
|
|
|
|
def test_batch_delete_partition_with_bad_partitions():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("glue", region_name="us-east-1")
|
|
|
|
database_name = "myspecialdatabase"
|
|
|
|
table_name = "myfirsttable"
|
2019-06-11 19:14:28 +00:00
|
|
|
helpers.create_database(client, database_name)
|
|
|
|
helpers.create_table(client, database_name, table_name)
|
|
|
|
|
|
|
|
partition_inputs = []
|
|
|
|
for i in range(0, 20):
|
|
|
|
values = ["2018-10-{:2}".format(i)]
|
2019-10-31 15:44:26 +00:00
|
|
|
part_input = helpers.create_partition_input(
|
|
|
|
database_name, table_name, values=values
|
|
|
|
)
|
2019-06-11 19:14:28 +00:00
|
|
|
partition_inputs.append(part_input)
|
|
|
|
|
|
|
|
client.batch_create_partition(
|
|
|
|
DatabaseName=database_name,
|
|
|
|
TableName=table_name,
|
2019-10-31 15:44:26 +00:00
|
|
|
PartitionInputList=partition_inputs,
|
2019-06-11 19:14:28 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
partition_values = [{"Values": p["Values"]} for p in partition_inputs]
|
|
|
|
|
|
|
|
partition_values.insert(5, {"Values": ["2018-11-01"]})
|
|
|
|
partition_values.insert(10, {"Values": ["2018-11-02"]})
|
|
|
|
partition_values.insert(15, {"Values": ["2018-11-03"]})
|
|
|
|
|
|
|
|
response = client.batch_delete_partition(
|
|
|
|
DatabaseName=database_name,
|
|
|
|
TableName=table_name,
|
|
|
|
PartitionsToDelete=partition_values,
|
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response.should.have.key("Errors")
|
|
|
|
response["Errors"].should.have.length_of(3)
|
|
|
|
error_partitions = map(lambda x: x["PartitionValues"], response["Errors"])
|
|
|
|
["2018-11-01"].should.be.within(error_partitions)
|
|
|
|
["2018-11-02"].should.be.within(error_partitions)
|
|
|
|
["2018-11-03"].should.be.within(error_partitions)
|