Prepare release 4.0.6 (#5514)
This commit is contained in:
parent
9340335d73
commit
9cd855032d
21
CHANGELOG.md
21
CHANGELOG.md
@ -1,6 +1,27 @@
|
|||||||
Moto Changelog
|
Moto Changelog
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
4.0.6
|
||||||
|
-----
|
||||||
|
Docker Digest for 4.0.6: <autopopulateddigest>
|
||||||
|
|
||||||
|
General:
|
||||||
|
* Moto can now be seeded, which will make identifiers deterministic.
|
||||||
|
See http://docs.getmoto.org/en/latest/docs/configuration/recorder/index.html
|
||||||
|
* The format for access-key and role ids has been changed, and is now generated using the same algorithm that AWS uses
|
||||||
|
|
||||||
|
Miscellaneous:
|
||||||
|
* AWSLambda:add_permission() now properly handles the PrincipalOrgID-param
|
||||||
|
* DynamoDB:update_item() now validates duplicate UpdateExpressions
|
||||||
|
* EC2 now exposes instance types in the correct availability zones for us-west-1 (us-west-1a and us-west-1b)
|
||||||
|
* EC2 has various improvements around the handling of RouteTableAssociations
|
||||||
|
* Glue:get_tables() now supports the Expression-parameter
|
||||||
|
* Organizations:create_organization() now uses a default value for FeatureSet=ALL
|
||||||
|
* RDS:describe_db_subnet_groups() now returns the DBSubnetGroupArn-attribute
|
||||||
|
* S3:upload_file() now supports the ExtraArgs: ChecksumAlgorithm-parameter
|
||||||
|
* SSM:list_commands() now returns the DeliveryTimedOutCount-attribute
|
||||||
|
|
||||||
|
|
||||||
4.0.5
|
4.0.5
|
||||||
-----
|
-----
|
||||||
Docker Digest for 4.0.5: _sha256:d18f760f3498b212b0c8c205c9c28c2b41e8c7a108f44e1bd1d7ee86dfc37c03_
|
Docker Digest for 4.0.5: _sha256:d18f760f3498b212b0c8c205c9c28c2b41e8c7a108f44e1bd1d7ee86dfc37c03_
|
||||||
|
@ -2878,20 +2878,20 @@
|
|||||||
<summary>20% implemented</summary>
|
<summary>20% implemented</summary>
|
||||||
|
|
||||||
- [X] batch_create_partition
|
- [X] batch_create_partition
|
||||||
- [X] batch_delete_connection
|
- [ ] batch_delete_connection
|
||||||
- [X] batch_delete_partition
|
- [X] batch_delete_partition
|
||||||
- [X] batch_delete_table
|
- [X] batch_delete_table
|
||||||
- [X] batch_delete_table_version
|
- [ ] batch_delete_table_version
|
||||||
- [ ] batch_get_blueprints
|
- [ ] batch_get_blueprints
|
||||||
- [ ] batch_get_crawlers
|
- [ ] batch_get_crawlers
|
||||||
- [ ] batch_get_custom_entity_types
|
- [ ] batch_get_custom_entity_types
|
||||||
- [ ] batch_get_dev_endpoints
|
- [ ] batch_get_dev_endpoints
|
||||||
- [ ] batch_get_jobs
|
- [ ] batch_get_jobs
|
||||||
- [ ] batch_get_partition
|
- [X] batch_get_partition
|
||||||
- [ ] batch_get_triggers
|
- [ ] batch_get_triggers
|
||||||
- [ ] batch_get_workflows
|
- [ ] batch_get_workflows
|
||||||
- [ ] batch_stop_job_run
|
- [ ] batch_stop_job_run
|
||||||
- [ ] batch_update_partition
|
- [X] batch_update_partition
|
||||||
- [ ] cancel_ml_task_run
|
- [ ] cancel_ml_task_run
|
||||||
- [ ] cancel_statement
|
- [ ] cancel_statement
|
||||||
- [ ] check_schema_version_validity
|
- [ ] check_schema_version_validity
|
||||||
@ -4625,7 +4625,7 @@
|
|||||||
|
|
||||||
## rds
|
## rds
|
||||||
<details>
|
<details>
|
||||||
<summary>28% implemented</summary>
|
<summary>29% implemented</summary>
|
||||||
|
|
||||||
- [ ] add_role_to_db_cluster
|
- [ ] add_role_to_db_cluster
|
||||||
- [ ] add_role_to_db_instance
|
- [ ] add_role_to_db_instance
|
||||||
@ -4646,7 +4646,7 @@
|
|||||||
- [ ] create_db_cluster_parameter_group
|
- [ ] create_db_cluster_parameter_group
|
||||||
- [X] create_db_cluster_snapshot
|
- [X] create_db_cluster_snapshot
|
||||||
- [X] create_db_instance
|
- [X] create_db_instance
|
||||||
- [ ] create_db_instance_read_replica
|
- [X] create_db_instance_read_replica
|
||||||
- [X] create_db_parameter_group
|
- [X] create_db_parameter_group
|
||||||
- [ ] create_db_proxy
|
- [ ] create_db_proxy
|
||||||
- [ ] create_db_proxy_endpoint
|
- [ ] create_db_proxy_endpoint
|
||||||
|
@ -26,20 +26,20 @@ glue
|
|||||||
|start-h3| Implemented features for this service |end-h3|
|
|start-h3| Implemented features for this service |end-h3|
|
||||||
|
|
||||||
- [X] batch_create_partition
|
- [X] batch_create_partition
|
||||||
- [X] batch_delete_connection
|
- [ ] batch_delete_connection
|
||||||
- [X] batch_delete_partition
|
- [X] batch_delete_partition
|
||||||
- [X] batch_delete_table
|
- [X] batch_delete_table
|
||||||
- [X] batch_delete_table_version
|
- [ ] batch_delete_table_version
|
||||||
- [ ] batch_get_blueprints
|
- [ ] batch_get_blueprints
|
||||||
- [ ] batch_get_crawlers
|
- [ ] batch_get_crawlers
|
||||||
- [ ] batch_get_custom_entity_types
|
- [ ] batch_get_custom_entity_types
|
||||||
- [ ] batch_get_dev_endpoints
|
- [ ] batch_get_dev_endpoints
|
||||||
- [ ] batch_get_jobs
|
- [ ] batch_get_jobs
|
||||||
- [ ] batch_get_partition
|
- [X] batch_get_partition
|
||||||
- [ ] batch_get_triggers
|
- [ ] batch_get_triggers
|
||||||
- [ ] batch_get_workflows
|
- [ ] batch_get_workflows
|
||||||
- [ ] batch_stop_job_run
|
- [ ] batch_stop_job_run
|
||||||
- [ ] batch_update_partition
|
- [X] batch_update_partition
|
||||||
- [ ] cancel_ml_task_run
|
- [ ] cancel_ml_task_run
|
||||||
- [ ] cancel_statement
|
- [ ] cancel_statement
|
||||||
- [ ] check_schema_version_validity
|
- [ ] check_schema_version_validity
|
||||||
|
@ -44,7 +44,7 @@ rds
|
|||||||
- [ ] create_db_cluster_parameter_group
|
- [ ] create_db_cluster_parameter_group
|
||||||
- [X] create_db_cluster_snapshot
|
- [X] create_db_cluster_snapshot
|
||||||
- [X] create_db_instance
|
- [X] create_db_instance
|
||||||
- [ ] create_db_instance_read_replica
|
- [X] create_db_instance_read_replica
|
||||||
- [X] create_db_parameter_group
|
- [X] create_db_parameter_group
|
||||||
- [ ] create_db_proxy
|
- [ ] create_db_proxy
|
||||||
- [ ] create_db_proxy_endpoint
|
- [ ] create_db_proxy_endpoint
|
||||||
|
@ -605,6 +605,96 @@ class GlueBackend(BaseBackend):
|
|||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
def batch_delete_table(self, database_name, tables):
|
||||||
|
errors = []
|
||||||
|
for table_name in tables:
|
||||||
|
try:
|
||||||
|
self.delete_table(database_name, table_name)
|
||||||
|
except TableNotFoundException:
|
||||||
|
errors.append(
|
||||||
|
{
|
||||||
|
"TableName": table_name,
|
||||||
|
"ErrorDetail": {
|
||||||
|
"ErrorCode": "EntityNotFoundException",
|
||||||
|
"ErrorMessage": "Table not found",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return errors
|
||||||
|
|
||||||
|
def batch_get_partition(self, database_name, table_name, partitions_to_get):
|
||||||
|
table = self.get_table(database_name, table_name)
|
||||||
|
|
||||||
|
partitions = []
|
||||||
|
for values in partitions_to_get:
|
||||||
|
try:
|
||||||
|
p = table.get_partition(values=values["Values"])
|
||||||
|
partitions.append(p.as_dict())
|
||||||
|
except PartitionNotFoundException:
|
||||||
|
continue
|
||||||
|
return partitions
|
||||||
|
|
||||||
|
def batch_create_partition(self, database_name, table_name, partition_input):
|
||||||
|
table = self.get_table(database_name, table_name)
|
||||||
|
|
||||||
|
errors_output = []
|
||||||
|
for part_input in partition_input:
|
||||||
|
try:
|
||||||
|
table.create_partition(part_input)
|
||||||
|
except PartitionAlreadyExistsException:
|
||||||
|
errors_output.append(
|
||||||
|
{
|
||||||
|
"PartitionValues": part_input["Values"],
|
||||||
|
"ErrorDetail": {
|
||||||
|
"ErrorCode": "AlreadyExistsException",
|
||||||
|
"ErrorMessage": "Partition already exists.",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return errors_output
|
||||||
|
|
||||||
|
def batch_update_partition(self, database_name, table_name, entries):
|
||||||
|
table = self.get_table(database_name, table_name)
|
||||||
|
|
||||||
|
errors_output = []
|
||||||
|
for entry in entries:
|
||||||
|
part_to_update = entry["PartitionValueList"]
|
||||||
|
part_input = entry["PartitionInput"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
table.update_partition(part_to_update, part_input)
|
||||||
|
except PartitionNotFoundException:
|
||||||
|
errors_output.append(
|
||||||
|
{
|
||||||
|
"PartitionValueList": part_to_update,
|
||||||
|
"ErrorDetail": {
|
||||||
|
"ErrorCode": "EntityNotFoundException",
|
||||||
|
"ErrorMessage": "Partition not found.",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return errors_output
|
||||||
|
|
||||||
|
def batch_delete_partition(self, database_name, table_name, parts):
|
||||||
|
table = self.get_table(database_name, table_name)
|
||||||
|
|
||||||
|
errors_output = []
|
||||||
|
for part_input in parts:
|
||||||
|
values = part_input.get("Values")
|
||||||
|
try:
|
||||||
|
table.delete_partition(values)
|
||||||
|
except PartitionNotFoundException:
|
||||||
|
errors_output.append(
|
||||||
|
{
|
||||||
|
"PartitionValues": values,
|
||||||
|
"ErrorDetail": {
|
||||||
|
"ErrorCode": "EntityNotFoundException",
|
||||||
|
"ErrorMessage": "Partition not found",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return errors_output
|
||||||
|
|
||||||
|
|
||||||
class FakeDatabase(BaseModel):
|
class FakeDatabase(BaseModel):
|
||||||
def __init__(self, database_name, database_input):
|
def __init__(self, database_name, database_input):
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
from moto.core.responses import BaseResponse
|
from moto.core.responses import BaseResponse
|
||||||
from .exceptions import (
|
|
||||||
PartitionAlreadyExistsException,
|
|
||||||
PartitionNotFoundException,
|
|
||||||
TableNotFoundException,
|
|
||||||
)
|
|
||||||
from .models import glue_backends
|
from .models import glue_backends
|
||||||
|
|
||||||
|
|
||||||
@ -119,20 +114,8 @@ class GlueResponse(BaseResponse):
|
|||||||
def batch_delete_table(self):
|
def batch_delete_table(self):
|
||||||
database_name = self.parameters.get("DatabaseName")
|
database_name = self.parameters.get("DatabaseName")
|
||||||
|
|
||||||
errors = []
|
tables = self.parameters.get("TablesToDelete")
|
||||||
for table_name in self.parameters.get("TablesToDelete"):
|
errors = self.glue_backend.batch_delete_table(database_name, tables)
|
||||||
try:
|
|
||||||
self.glue_backend.delete_table(database_name, table_name)
|
|
||||||
except TableNotFoundException:
|
|
||||||
errors.append(
|
|
||||||
{
|
|
||||||
"TableName": table_name,
|
|
||||||
"ErrorDetail": {
|
|
||||||
"ErrorCode": "EntityNotFoundException",
|
|
||||||
"ErrorMessage": "Table not found",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
out = {}
|
out = {}
|
||||||
if errors:
|
if errors:
|
||||||
@ -166,15 +149,9 @@ class GlueResponse(BaseResponse):
|
|||||||
table_name = self.parameters.get("TableName")
|
table_name = self.parameters.get("TableName")
|
||||||
partitions_to_get = self.parameters.get("PartitionsToGet")
|
partitions_to_get = self.parameters.get("PartitionsToGet")
|
||||||
|
|
||||||
table = self.glue_backend.get_table(database_name, table_name)
|
partitions = self.glue_backend.batch_get_partition(
|
||||||
|
database_name, table_name, partitions_to_get
|
||||||
partitions = []
|
)
|
||||||
for values in partitions_to_get:
|
|
||||||
try:
|
|
||||||
p = table.get_partition(values=values["Values"])
|
|
||||||
partitions.append(p.as_dict())
|
|
||||||
except PartitionNotFoundException:
|
|
||||||
continue
|
|
||||||
|
|
||||||
return json.dumps({"Partitions": partitions})
|
return json.dumps({"Partitions": partitions})
|
||||||
|
|
||||||
@ -191,22 +168,10 @@ class GlueResponse(BaseResponse):
|
|||||||
def batch_create_partition(self):
|
def batch_create_partition(self):
|
||||||
database_name = self.parameters.get("DatabaseName")
|
database_name = self.parameters.get("DatabaseName")
|
||||||
table_name = self.parameters.get("TableName")
|
table_name = self.parameters.get("TableName")
|
||||||
table = self.glue_backend.get_table(database_name, table_name)
|
partition_input = self.parameters.get("PartitionInputList")
|
||||||
|
errors_output = self.glue_backend.batch_create_partition(
|
||||||
errors_output = []
|
database_name, table_name, partition_input
|
||||||
for part_input in self.parameters.get("PartitionInputList"):
|
)
|
||||||
try:
|
|
||||||
table.create_partition(part_input)
|
|
||||||
except PartitionAlreadyExistsException:
|
|
||||||
errors_output.append(
|
|
||||||
{
|
|
||||||
"PartitionValues": part_input["Values"],
|
|
||||||
"ErrorDetail": {
|
|
||||||
"ErrorCode": "AlreadyExistsException",
|
|
||||||
"ErrorMessage": "Partition already exists.",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
out = {}
|
out = {}
|
||||||
if errors_output:
|
if errors_output:
|
||||||
@ -228,25 +193,11 @@ class GlueResponse(BaseResponse):
|
|||||||
def batch_update_partition(self):
|
def batch_update_partition(self):
|
||||||
database_name = self.parameters.get("DatabaseName")
|
database_name = self.parameters.get("DatabaseName")
|
||||||
table_name = self.parameters.get("TableName")
|
table_name = self.parameters.get("TableName")
|
||||||
table = self.glue_backend.get_table(database_name, table_name)
|
entries = self.parameters.get("Entries")
|
||||||
|
|
||||||
errors_output = []
|
errors_output = self.glue_backend.batch_update_partition(
|
||||||
for entry in self.parameters.get("Entries"):
|
database_name, table_name, entries
|
||||||
part_to_update = entry["PartitionValueList"]
|
)
|
||||||
part_input = entry["PartitionInput"]
|
|
||||||
|
|
||||||
try:
|
|
||||||
table.update_partition(part_to_update, part_input)
|
|
||||||
except PartitionNotFoundException:
|
|
||||||
errors_output.append(
|
|
||||||
{
|
|
||||||
"PartitionValueList": part_to_update,
|
|
||||||
"ErrorDetail": {
|
|
||||||
"ErrorCode": "EntityNotFoundException",
|
|
||||||
"ErrorMessage": "Partition not found.",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
out = {}
|
out = {}
|
||||||
if errors_output:
|
if errors_output:
|
||||||
@ -267,23 +218,11 @@ class GlueResponse(BaseResponse):
|
|||||||
def batch_delete_partition(self):
|
def batch_delete_partition(self):
|
||||||
database_name = self.parameters.get("DatabaseName")
|
database_name = self.parameters.get("DatabaseName")
|
||||||
table_name = self.parameters.get("TableName")
|
table_name = self.parameters.get("TableName")
|
||||||
table = self.glue_backend.get_table(database_name, table_name)
|
parts = self.parameters.get("PartitionsToDelete")
|
||||||
|
|
||||||
errors_output = []
|
errors_output = self.glue_backend.batch_delete_partition(
|
||||||
for part_input in self.parameters.get("PartitionsToDelete"):
|
database_name, table_name, parts
|
||||||
values = part_input.get("Values")
|
)
|
||||||
try:
|
|
||||||
table.delete_partition(values)
|
|
||||||
except PartitionNotFoundException:
|
|
||||||
errors_output.append(
|
|
||||||
{
|
|
||||||
"PartitionValues": values,
|
|
||||||
"ErrorDetail": {
|
|
||||||
"ErrorCode": "EntityNotFoundException",
|
|
||||||
"ErrorMessage": "Partition not found",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
out = {}
|
out = {}
|
||||||
if errors_output:
|
if errors_output:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user