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
17 stars 3 forks source link

support map type #7

Closed kapilt closed 2 years ago

kapilt commented 2 years 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 2 years 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 2 years ago

Thanks for the pointer!

kapilt commented 2 years 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.