」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 如何在 Bigquery 參數化查詢中傳遞結構數組

如何在 Bigquery 參數化查詢中傳遞結構數組

發佈於2024-11-08
瀏覽:397

How to pass an Array of Structs in Bigquery

在Google的Bigquery中,SQL查詢可以參數化。如果您不熟悉這個概念,它基本上意味著您可以將 SQL 查詢編寫為參數化模板,如下所示:

INSERT INTO mydataset.mytable(columnA, columnB)
    VALUES (@valueA, @valueB)

並分別傳遞數值。這有很多好處:

  • 查詢比透過字串連接建構的查詢更​​具可讀性
  • 代碼更加健全和工業化
  • 這是針對 SQL 注入攻擊的強大保護(強制 XKCD)

乍一看,從 Python 腳本傳遞查詢參數似乎很簡單。例如:

from google.cloud.bigquery import (
    Client,
    ScalarQueryParameter,
    ArrayQueryParameter,
    StructQueryParameter,
    QueryJobConfig,
)

client=Client()

client.query("
INSERT INTO mydataset.mytable(columnA, columnB)
    VALUES (@valueA, @valueB)
", job_config=QueryJobConfig(
    query_parameters=[
        ScalarQueryParameter("valueA","STRING","A"), 
        ScalarQueryParameter("valueB","STRING","B")
])

上面的範例在 A 列和 B 列中插入簡單(「標量」)值。但您也可以傳遞更複雜的參數:

  • 陣列(ArrayQueryParameter)
  • 結構(StructQueryParameter)

當您想要插入結構數組時,就會出現問題:有很多陷阱,幾乎沒有文檔,網絡上有關該主題的資源也很少。本文的目標就是填補這一空白。

如何使用參數化查詢在 bigquery 中持久保存結構數組

讓我們定義要儲存在目標表中的以下物件

from dataclasses import dataclass

@dataclass
class Country:
    name: str
    capital_city: str

@dataclass
class Continent:
    name: str
    countries: list[Country]

透過呼叫此參數化查詢

query = UPDATE continents SET countries=@countries WHERE name="Oceania"

遵循淺薄文件的第一次嘗試是

client.query(query, 
    job_config=QueryJobConfig(query_parameters=[
        ArrayQueryParameter("countries", "RECORD", [
             {name="New Zealand", capital_city="Wellington"},
             {name="Fiji", capital_city="Suva"} ...]
]))

這會慘敗

AttributeError:'dict'物件沒有屬性'to_api_repr'

問題 1:ArrayQueryParameter 的值必須是 StructQueryParameter 的實例

事實證明,建構子的第三個參數 - value - 必須是 StructQueryParameter 實例的集合,而不是直接想要的值。那麼讓我們來建構它們:

client.query(query, 
job_config=QueryJobConfig(query_parameters=[
    ArrayQueryParameter("countries", "RECORD", [
    StructQueryParameter("countries",
        ScalarQueryParameter("name", "STRING", ct.name), 
        ScalarQueryParameter("capital_city", "STRING", ct.capital_city)
    )
    for ct in countries])
]))

這次有效...直到你試著設定一個空數組

client.query(query, 
    job_config=QueryJobConfig(
    query_parameters=[
        ArrayQueryParameter("countries", "RECORD", [])
]))

ValueError:缺少空數組的詳細結構項類型信息,請提供 StructQueryParameterType 實例。

陷阱 n°2:提供完整的結構類型作為第二個參數

錯誤訊息非常清楚:「RECORD」不足以讓 Bigquery 知道如何處理空數組。它需要完整詳細的結構。就這樣吧

client.query(query, job_config=QueryJobConfig(query_parameters=[
    ArrayQueryParameter("countries",
        StructQueryParameterType(
            ScalarQueryParameterType("STRING","name"),
            ScalarQueryParameterType("STRING","capital_city")
        ), [])
]))

(注意 ...ParameterType 建構子的參數順序與 ...Parameter 建構子相反。這只是路上的另一個陷阱...)

現在它也適用於空數組,耶!

最後一個需要注意的問題:StructQueryParameterType 的每個子欄位都必須有一個名稱,即使第二個參數(名稱)在建構函式中是可選的。它實際上對於子字段是強制性的,否則你會得到一種新的錯誤

空結構欄位名稱

我想這就是我們完成查詢參數中記錄數組的使用所需要知道的一切,我希望這會有所幫助!


感謝您的閱讀!我是 Matthieu,Stack Labs 的資料工程師。
如果您想了解 Stack Labs 資料平台或加入熱情的資料工程團隊,請與我們聯絡。


Denys Nevozhai 在 Unsplash 上的照片

版本聲明 本文轉載於:https://dev.to/stack-labs/how-to-pass-an-array-of-structs-in-bigquerys-parameterized-queries-39nm?1如有侵犯,請聯絡study_golang@163 .com刪除
最新教學 更多>
  • 使用 JavaScript 創建令人著迷的粒子動畫
    使用 JavaScript 創建令人著迷的粒子動畫
    這就是我們要創建的,將滑鼠移到粒子上即可查看效果。 在本文中,我將引導您完成使用 JavaScript 和 HTML5 畫佈建立迷人粒子動畫的過程。該專案不僅增強了網頁的美觀性,而且還是深入研究一些有趣的編碼概念的絕佳機會。讓我們開始吧! 項目概況 動畫的特點是粒子圍繞中心點以圓...
    程式設計 發佈於2024-11-08
  • 使用 JavaScript 釋放大型語言模型的力量:實際應用程式
    使用 JavaScript 釋放大型語言模型的力量:實際應用程式
    In recent years, Large Language Models (LLMs) have revolutionized how we interact with technology, enabling machines to understand and generate human-...
    程式設計 發佈於2024-11-08
  • Bootstrap 與 Tailwind 整合:Pro 與 Contro | Bootstrap 和 Tailwind:優點和缺點
    Bootstrap 與 Tailwind 整合:Pro 與 Contro | Bootstrap 和 Tailwind:優點和缺點
    简介 |介绍 意大利语: 本文有意大利语和英语版本。向下滚动查看英文版本。 英语: 本文有意大利语和英语版本。向下滚动查看英文版本。 意大利语版 Bootstrap 和 Tailwind 集成简介 近年来,Bootstrap和Tailwind CSS已经成为前端开发最流行的两个框架。 Boot...
    程式設計 發佈於2024-11-08
  • 我們如何使用 Gin 框架來增強 Go 應用程式中的錯誤處理?
    我們如何使用 Gin 框架來增強 Go 應用程式中的錯誤處理?
    更好的錯誤處理問題在Go應用程式中,我們如何透過定義自訂錯誤類型(例如appError和實現自定義處理程序來捕獲錯誤並將其寫入回應中?正常的流程邏輯。 ))建立錯誤中間件:func JSONAppErrorReporter() gin.HandlerFunc { 返回 func(c *gin...
    程式設計 發佈於2024-11-08
  • DOM API 終極指南
    DOM API 終極指南
    // Selecting Elements: document is not the real DOM element. document.documentElement; // Select the entire page document.head; // Select the head doc...
    程式設計 發佈於2024-11-08
  • Python 中的實例方法與類別方法:什麼時候應該使用“self”和“cls”?
    Python 中的實例方法與類別方法:什麼時候應該使用“self”和“cls”?
    深入研究類別和實例方法的細微差別:Beyond Self 與ClsPython 增強提案(PEP) 8 建議使用“self”作為實例方法中的第一個參數,「cls」作為類別方法中的第一個參數。這種差異源自於這些方法在處理實例和類別時所扮演的不同角色。 實例方法:自我優勢實例方法在實例的實例上呼叫班級。...
    程式設計 發佈於2024-11-08
  • Node.js 傻瓜指南 - MongoDB 和 Fastify
    Node.js 傻瓜指南 - MongoDB 和 Fastify
    O que é Node.js? Node.js, uma plataforma construída sobre o motor de JavaScript V8 do Google Chrome, revolucionou o desenvolvimento backend n...
    程式設計 發佈於2024-11-08
  • 如何使用 Joda Time 將日期字串解析為 DateTime 物件並避免「無效格式」錯誤?
    如何使用 Joda Time 將日期字串解析為 DateTime 物件並避免「無效格式」錯誤?
    使用Joda Time 將日期字串解析為DateTime 物件處理日期和時間資料時,通常需要轉換日期作為字串儲存到結構化物件中以便進一步處理。 Joda Time 庫提供了一套全面的工具,用於處理 Java 中的日期和時間操作。 一個常見任務是將日期字串轉換為 DateTime 物件。但是,如果字串...
    程式設計 發佈於2024-11-08
  • 如何解決 PHP 中的「每個引號前都有斜線」問題?
    如何解決 PHP 中的「每個引號前都有斜線」問題?
    理解「引號前的斜槓」問題在某些情況下,PHP網頁可能會遇到提交表單資料導致添加一個每個雙引號前都有反斜線。此問題是由稱為“魔術引號”的伺服器配置功能引起的。 啟用魔術引號後,PHP 在向資料庫或表單提交發送或從資料庫或表單提交接收某些字符時,會自動轉義某些字符,包括雙引號。雖然這可以透過轉義惡意引號...
    程式設計 發佈於2024-11-08
  • ## 如何在 C++ 中將多維數組轉換為函式庫函數的指標?
    ## 如何在 C++ 中將多維數組轉換為函式庫函數的指標?
    在 C 中將多維數組轉換為指標 在 C 中,多維數組與指標不直接相容。當嘗試使用採用 double** 的函式庫函數時,使用簡單的強制轉換轉換 double4 陣列可能會導致錯誤。 要解決此問題,必須使陣列適應函數的介面。不要將整個陣列轉換為double**,而是建立指向每行開頭的臨時「索引」陣列:...
    程式設計 發佈於2024-11-08
  • 如何在 PHP 中非同步執行 cURL 請求?
    如何在 PHP 中非同步執行 cURL 請求?
    PHP中的非同步Curl請求在PHP中非同步執行curl post請求可以提高效能並防止潛在的延遲。以下是如何使用不同的方法實現此目的:使用非同步 cURL 函數使用curl_multi_*時,您可以同時執行多個 cURL 要求。以下是一個範例程式碼:$curl = curl_init($reque...
    程式設計 發佈於2024-11-08
  • 如何將 Boehm 垃圾收集器與 C++ 標準庫類別(如“std::vector”和“std::string”)整合?
    如何將 Boehm 垃圾收集器與 C++ 標準庫類別(如“std::vector”和“std::string”)整合?
    將Boehm 垃圾收集器與C 標準庫結合使用開發多線程C 應用程式時,Boehm 保守的垃圾收集器對於簡化記憶體非常有用管理。這就提出瞭如何將 Boehm GC 與 C 標準函式庫的類別(如 std::map 和 std::vector)整合的問題。 一種方法涉及重新定義全域運算子 ::new 以使...
    程式設計 發佈於2024-11-08
  • 如何管理具有共用欄位的類似 Go 結構的函數?
    如何管理具有共用欄位的類似 Go 結構的函數?
    Go 最佳實踐:管理具有共享字段的相似結構體的函數在Go 中,經常會遇到具有相似字段的多個結構體,並且需要對它們執行相同的操作。為了在保持靈活性的同時避免程式碼重複,請考慮以下策略:為共享欄位建立自訂類型:如果共用欄位是簡單資料類型(例如,字串),考慮為其定義自訂類型。這允許您將方法附加到自訂類型,...
    程式設計 發佈於2024-11-08
  • 如何在Ajax資料載入過程中顯示進度條?
    如何在Ajax資料載入過程中顯示進度條?
    如何在Ajax 資料載入期間顯示進度條處理使用者觸發的事件(例如從下拉方塊中選擇值)時,通常會使用非同步擷取資料阿賈克斯。在獲取數據時,向用戶提供正在發生某事的視覺指示是有益的。本文探討了一種在 Ajax 請求期間顯示進度條的方法。 使用 Ajax 實作進度條要建立一個準確追蹤 Ajax 呼叫進度的...
    程式設計 發佈於2024-11-08
  • 如何在 PHP 中透過 SSH 安全連接到遠端 MySQL 伺服器?
    如何在 PHP 中透過 SSH 安全連接到遠端 MySQL 伺服器?
    在PHP 中透過SSH 安全連接到遠端MySQL 伺服器要為PHP 資料庫連線建立安全隧道,以下SSH 隧道解決方案提供了一種強大的方法。 SSH 隧道設定建立通往 MySQL 資料庫伺服器的 SSH 隧道。為此,請使用以下命令:ssh -fNg -L 3307:10.3.1.55:3306 [em...
    程式設計 發佈於2024-11-08

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3