Запрос вложенных объектов в Cosmos DB

#python #azure #azure-cosmosdb #pyodbc #azure-cosmosdb-sqlapi

Вопрос:

Я просмотрел несколько ответов и попробовал различные подходы для запроса вложенных объектов, которые у меня есть в Cosmos DB. База данных содержит довольно большое количество объектов типа json различных типов. Мне удалось успешно запросить подобъекты первого объекта в списке, но не последующих объектов.

Сам объект выглядит так:

 {
    "id": "d44c1ff6-d5b0-41b0-b84c-2a6c20f99ada",
    "deviceUID": "10203040501020304051-8",
    "time": "2021-10-27T12:49:53.1174041Z",
    "connectorId": 1,
    "meterValues": {
        "eairo": 1013363236,
        "cio": 4
    },
    "hash": "8ADAED5BBF663AAFE93644CA071573906CC409F70231105F10C5CEE5AE8FC341"
}
 

И мое подключение и запрос заключаются в следующем:

 cnxn: pyodbc.Connection = pyodbc.connect(
"""DRIVER={CData ODBC Driver for Cosmos DB};
   AccountEndpoint=x;
   AccountKey=y;""")
df = pd.read_sql_query("SELECT m.id, m.deviceUID, m.time, m.meterValues.eairo FROM metering m WHERE m.deviceUID <> null", cnxn)
 

Это та m.meterValues.eairo часть ВЫБОРА, которая оказывается проблематичной. Сообщение об ошибке выглядит следующим образом:

 pandas.io.sql.DatabaseError: Execution failed on sql 'SELECT m.id, m.deviceUID, m.time, m.meterValues.eairo FROM metering m WHERE m.deviceUID <> null': ('HY000', "[HY000] No table found with the alias 'meterValues'. (-1) (SQLExecDirectW)")
 

Есть идеи, где я могу ошибиться?

Комментарии:

1. Тебе не нужно говорить FROM metering m — просто скажи FROM m . Помимо этого: Вам следует попробовать использовать собственный пакет SDK Python для Cosmos DB, а не библиотеку ODBC (помните, что Cosmos DB не является собственной реляционной базой данных, и ее синтаксис SQL является подмножеством того, что вы найдете в реляционной базе данных). Я подозреваю, что у вас будут лучшие результаты, так как в настоящее время вы пытаетесь принудить Cosmos DB к интерфейсу реляционной базы данных.

2. Отлично, спасибо за это, Дэвид, SDK сделал свою работу.

Ответ №1:

Надо отдать должное Дэвиду за то, что SDK легко справился с этим.

Кодируется следующим образом:

 from azure.cosmos import CosmosClient
import json

url = 'x'
key = 'y'
client = CosmosClient(url, credential=key)

database = client.get_database_client('z')
container = database.get_container_client('metering')

for item in container.query_items(
        query="SELECT m.id, m.deviceUID, m.time, m.meterValues.eairo FROM 
        metering m WHERE m.deviceUID <> null",
        enable_cross_partition_query=True):
    print(json.dumps(item, indent=True))