passren / PyDynamoDB

PyDynamoDB is a Python DB API 2.0 (PEP 249) client for Amazon DynamoDB. A SQLAlchemy dialect is offered as well. Superset official database driver.
Other
16 stars 2 forks source link

support map type #7

Closed kapilt closed 1 year ago

kapilt commented 1 year ago

interesting project, one thought would be to add support for a custom type for maps https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.data-types.html

passren commented 1 year ago

@kapilt Thanks for your idea. It indeed support all data types listed in the AWS doc, including map (even the nested map). Please refer to the sample here PyDynamoDB is able to pass python built-in-type data to a qmark parameter in Partiql and convert the response to built-in type data.

Insert map data into ddb:

        sql_one_row_2_1_ = (
            """
            INSERT INTO %s VALUE {
                'key_partition': ?, 'key_sort': ?, 'col_nested_list': ?, 'col_nested_map': ?
            }
        """
            % TESTCASE01_TABLE
        )
        params_2_1_ = [
            "test_one_row_2",
            1,
            [
                "Hello",
                "World",
                1.0,
                b"1",
                {1, 2, 3},
                {"1", "2", "3"},
                {"name": "test case 3", "version": 1.0},
            ],
            {
                "name": "test case 3",
                "version": 1.0,
                "list": ["Hello", "World", {1, 2, 3}, {"1", "2"}, 2],
                "map": {"str": "Best", "num": 1, "chinese": u"你好"},
            },
        ]
        cursor.execute(sql_one_row_2_1_, params_2_1_)

Get map data from DDB:

        cursor.execute(
            """
            SELECT col_nested_list, col_nested_map FROM %s
            WHERE key_partition = ?
            AND key_sort = ?
        """
            % TESTCASE01_TABLE,
            ["test_one_row_2", 1],
        )
        row = cursor.fetchone()
        desc = cursor.description
        assert self._get_value_by_column_name(desc, row, "col_nested_list") == [
                                                    "Hello", "World", 1.0,
                                                    b"1", {1, 2, 3}, {"1", "2", "3"},
                                                    {"name": "test case 3", "version": 1.0},
                                                ]
        assert self._get_value_by_column_name(desc, row, "col_nested_map") == {
                                                    "name": "test case 3",
                                                    "version": 1.0,
                                                    "list": ["Hello", "World", {1, 2, 3}, {"1", "2"}, 2],
                                                    "map": {"str": "Best", "num": 1, "chinese": u"你好"},
                                                }
kapilt commented 1 year ago

Thanks for the pointer!

kapilt commented 1 year ago

that's helpful on dbapi, I think the context I meant was a custom type for sqlalchemy to take advantage of key/value retrieval and set.