Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu makalede, olarak VARIANTdepolanan yarı yapılandırılmış verileri sorgulama ve dönüştürme işlemleri açıklanmaktadır.
VARIANT Veri türü Databricks Runtime 15.4 ve üzerinde kullanılabilir.
Azure Databricks, yarı yapılandırılmış veriler için JSON dizeleri yerine VARIANT kullanılmasını önerir. Şu anda geçiş yapmak isteyen JSON dizelerini kullanan kullanıcılar için bkz . Değişken JSON dizelerinden nasıl farklıdır?.
JSON dizeleri olarak depolanan yarı yapılandırılmış verileri sorgulamak için bkz. JSON dizelerini sorgulama.
Dikkat
VARIANT sütunlar kümeleme anahtarları, bölümler veya Z sırası anahtarları için kullanılamaz.
VARIANT veri türü karşılaştırmalar, gruplandırma, sıralama ve ayarlama işlemleri için kullanılamaz. Sınırlamaların tam listesi için bkz. Sınırlamalar.
Değişken sütunlu tablo oluşturma
Değişken sütun oluşturmak için işlevini (parse_json veya Python) kullanın.
Yüksek derecede iç içe geçmiş veriler olarak depolanan VARIANT ile bir tablo oluşturmak için aşağıdakileri çalıştırın. (Bu veriler bu sayfadaki diğer örneklerde kullanılır.)
Piton
# Create a table with a variant column
store_data='''
{
"store":{
"fruit":[
{"weight":8,"type":"apple"},
{"weight":9,"type":"pear"}
],
"basket":[
[1,2,{"b":"y","a":"x"}],
[3,4],
[5,6]
],
"book":[
{
"author":"Nigel Rees",
"title":"Sayings of the Century",
"category":"reference",
"price":8.95
},
{
"author":"Herman Melville",
"title":"Moby Dick",
"category":"fiction",
"price":8.99,
"isbn":"0-553-21311-3"
},
{
"author":"J. R. R. Tolkien",
"title":"The Lord of the Rings",
"category":"fiction",
"reader":[
{"age":25,"name":"bob"},
{"age":26,"name":"jack"}
],
"price":22.99,
"isbn":"0-395-19395-8"
}
],
"bicycle":{
"price":19.95,
"color":"red"
}
},
"owner":"amy",
"zip code":"94025",
"fb:testid":"1234"
}
'''
# Create a DataFrame
df = spark.createDataFrame([(store_data,)], ["json"])
# Convert to a variant
df_variant = df.select(parse_json(col("json")).alias("raw"))
# Alternatively, create the DataFrame directly
# df_variant = spark.range(1).select(parse_json(lit(store_data)))
df_variant.display()
# Write out as a table
df_variant.write.saveAsTable("store_data")
SQL
-- Create a table with a variant column
CREATE TABLE store_data AS
SELECT parse_json(
'{
"store":{
"fruit": [
{"weight":8,"type":"apple"},
{"weight":9,"type":"pear"}
],
"basket":[
[1,2,{"b":"y","a":"x"}],
[3,4],
[5,6]
],
"book":[
{
"author":"Nigel Rees",
"title":"Sayings of the Century",
"category":"reference",
"price":8.95
},
{
"author":"Herman Melville",
"title":"Moby Dick",
"category":"fiction",
"price":8.99,
"isbn":"0-553-21311-3"
},
{
"author":"J. R. R. Tolkien",
"title":"The Lord of the Rings",
"category":"fiction",
"reader":[
{"age":25,"name":"bob"},
{"age":26,"name":"jack"}
],
"price":22.99,
"isbn":"0-395-19395-8"
}
],
"bicycle":{
"price":19.95,
"color":"red"
}
},
"owner":"amy",
"zip code":"94025",
"fb:testid":"1234"
}'
) as raw
SELECT * FROM store_data
Değişken sütunundaki alanları sorgulama
Bir değişken sütunundaki alanları ayıklamak için ayıklama yolunuzda JSON alanının adını belirten işlevini (variant_get veya Python) kullanın. Alan adları her zaman büyük/küçük harfe duyarlıdır.
Piton
# Extract a top-level field
df_variant.select(variant_get(col("raw"), "$.owner", "string")).display()
SQL
-- Extract a top-level field
SELECT variant_get(store_data.raw, '$.owner') AS owner FROM store_data
Bir değişken sütunundaki alanları sorgulamak için SQL söz dizimlerini de kullanabilirsiniz. bkz. variant_get için SQL kısaltması.
variant_get için SQL kısaltması
Azure Databricks'te JSON dizelerini ve diğer karmaşık veri türlerini sorgulamaya yönelik SQL söz dizimi, aşağıdakiler de dahil olmak üzere veriler için VARIANT geçerlidir:
- En üst düzey alanları seçmek için kullanın
:. - Kullanarak
.veya[<key>], adlandırılmış anahtarlara sahip iç içe alanları seçin. - Dizilerden değerleri seçmek için kullanın
[<index>].
SELECT raw:owner FROM store_data
+-------+
| owner |
+-------+
| "amy" |
+-------+
-- Enclose a field name that contains special characters in single quotes inside square brackets.
SELECT raw:['zip code'], raw:['fb:testid'] FROM store_data
+----------+-----------+
| zip code | fb:testid |
+----------+-----------+
| "94025" | "1234" |
+----------+-----------+
Söz ['<field>'] dizimi, alan adında boşluklar, nokta (), iki nokta üst üste (. ) ve köşeli ayraçlar (:[ ] dahil olmak üzere tüm özel karakterlerden kaçış sağlar. Azure Databricks, özel karakter içeren her alan adı için bu söz dizimini önerir. Örneğin, raw:['zip.code'] adlı bir alanı seçmek için zip.code veya raw:['A[1]'] adlı bir alanı seçmek için A[1] kullanın.
Arka uçlar boşluk veya iki nokta üst üste içeren alan adlarından da kaçış yapar, ancak noktalardan veya köşeli ayraçlardan kaçmaz. Nokta veya köşeli parantez içeren bir alan adı, ters tırnaklarla kaçışlandığında NULL döndürür; bu nedenle bu adlar için ['<field>'] söz dizimini kullanın.
PySpark'ta özel karakterler içeren alanları çıkarmak için, variant_get çıkarma yolunda aynı köşeli ayraç söz dizimini kullanın:
# Escape special characters in the extraction path
df_variant.select(variant_get(col("raw"), "$['zip.code']", "string"))
df_variant.select(variant_get(col("raw"), "$['A[1]']", "string"))
İç içe geçmiş değişken alanları ayıklama
Bir değişken sütunundan iç içe yerleştirilmiş alanları ayıklamak için, noktalı gösterim veya köşeli ayraç kullanarak bunları belirtin. Alan adları her zaman büyük/küçük harfe duyarlıdır.
Piton
# Use dot notation
df_variant.select(variant_get(col("raw"), "$.store.bicycle", "string")).display()
# Use brackets
df_variant.select(variant_get(col("raw"), "$.store['bicycle']", "string")).display()
Yol bulunamazsa, sonuç null türünde VariantVal olur.
SQL
-- Use dot notation
SELECT raw:store.bicycle FROM store_data
-- Use brackets
SELECT raw:store['bicycle'] FROM store_data
Yol bulunamazsa, sonuç NULL türünde VARIANT olur.
+-----------------+
| bicycle |
+-----------------+
| { |
| "color":"red", |
| "price":19.95 |
| } |
+-----------------+
Değişken dizilerden değerleri ayıklama
Dizilerdeki öğeleri ayıklamak için köşeli ayraçlarla dizin oluşturun. Dizinler 0 tabanlıdır.
Piton
# Index elements
df_variant.select((variant_get(col("raw"), "$.store.fruit[0]", "string")),(variant_get(col("raw"), "$.store.fruit[1]", "string"))).display()
SQL
-- Index elements
SELECT raw:store.fruit[0], raw:store.fruit[1] FROM store_data
+-------------------+------------------+
| fruit | fruit |
+-------------------+------------------+
| { | { |
| "type":"apple", | "type":"pear", |
| "weight":8 | "weight":9 |
| } | } |
+-------------------+------------------+
Yol bulunamazsa veya dizi dizini sınırların dışındaysa sonuç null olur.
Python'da çeşitlemelerle çalışma
Spark DataFrames'ten Python'a VariantVal varyantlar ayıklayabilir ve toPython ve toJson yöntemlerini kullanarak bu varyantlarla tek tek çalışabilirsiniz.
# toPython
data = [
('{"name": "Alice", "age": 25}',),
('["person", "electronic"]',),
('1',)
]
df_person = spark.createDataFrame(data, ["json"])
# Collect variants into a VariantVal
variants = df_person.select(parse_json(col("json")).alias("v")).collect()
VariantVal çıktıyı JSON dizesi olarak çıkar:
print(variants[0].v.toJson())
{"age":25,"name":"Alice"}
bir VariantVal öğesini Python nesnesine dönüştürme:
# First element is a dictionary
print(variants[0].v.toPython()["age"])
25
# Second element is a List
print(variants[1].v.toPython()[1])
electronic
# Third element is an Integer
print(variants[2].v.toPython())
1
Ayrıca VariantVal işlevini kullanarak VariantVal.parseJson oluşturabilirsiniz.
# parseJson to construct VariantVal's in Python
from pyspark.sql.types import VariantVal
variant = VariantVal.parseJson('{"a": 1}')
Değişkenini JSON dizesi olarak yazdırın:
print(variant.toJson())
{"a":1}
Değişkeni python nesnesine dönüştürün ve bir değer yazdırın:
print(variant.toPython()["a"])
1
Bir değişkenin şemasını döndürme
Bir değişkenin şemasını döndürmek için işlevini (schema_of_variant veya Python) kullanın.
Piton
# Return the schema of the variant
df_variant.select(schema_of_variant(col("raw"))).display()
SQL
-- Return the schema of the variant
SELECT schema_of_variant(raw) FROM store_data;
Bir gruptaki tüm değişkenlerin birleştirilmiş şemalarını döndürmek için işlevini (schema_of_variant_agg veya Python) kullanın.
Aşağıdaki örnekler şemayı ve ardından örnek veriler json_dataiçin birleştirilmiş şemayı döndürür.
Piton
json_data = [
('{"name": "Alice", "age": 25}',),
('{"id": 101, "department": "HR"}',),
('{"product": "Laptop", "price": 1200.50, "in_stock": true}',)
]
df_item = spark.createDataFrame(json_data, ["json"])
# Return the schema
df_item.select(parse_json(col("json")).alias("v")).select(schema_of_variant(col("v"))).display()
SQL
CREATE OR REPLACE TEMP VIEW json_data AS
SELECT '{"name": "Alice", "age": 25}' AS json UNION ALL
SELECT '{"id": 101, "department": "HR"}' UNION ALL
SELECT '{"product": "Laptop", "price": 1200.50, "in_stock": true}';
-- Return the schema
SELECT schema_of_variant(parse_json(json)) FROM json_data;
+-----------------------------------------------------------------+
| schema_of_variant(v) |
+-----------------------------------------------------------------+
| OBJECT<age: BIGINT, name: STRING> |
| OBJECT<department: STRING, id: BIGINT> |
| OBJECT<in_stock: BOOLEAN, price: DECIMAL(5,1), product: STRING> |
+-----------------------------------------------------------------+
Piton
# Return the combined schema
df.select(parse_json(col("json")).alias("v")).select(schema_of_variant_agg(col("v"))).display()
SQL
-- Return the combined schema
SELECT schema_of_variant_agg(parse_json(json)) FROM json_data;
+----------------------------------------------------------------------------------------------------------------------------+
| schema_of_variant(v) |
+----------------------------------------------------------------------------------------------------------------------------+
| OBJECT<age: BIGINT, department: STRING, id: BIGINT, in_stock: BOOLEAN, name: STRING, price: DECIMAL(5,1), product: STRING> |
+----------------------------------------------------------------------------------------------------------------------------+
Değişken nesneleri ve dizileri düzleştirme
Tablo variant_explode değerli oluşturucu işlevi (SQL veya Python), değişken dizileri ve nesneleri düzleştirme amacıyla kullanılabilir.
Piton
Bir değişkeni birden çok satıra genişletmek için tablo değerli işlevi (TVF) DataFrame API'sini kullanın:
spark.tvf.variant_explode(parse_json(lit(store_data))).display()
# To explode a nested field, first create a DataFrame with just the field
df_store_col = df_variant.select(variant_get(col("raw"), "$.store", "variant").alias("store"))
# Perform the explode with a lateral join and the outer function to return the new exploded DataFrame
df_store_exploded_lj = df_store_col.lateralJoin(spark.tvf.variant_explode(col("store").outer()))
df_store_exploded = df_store_exploded_lj.drop("store")
df_store_exploded.display()
SQL
Oluşturucu işlev olduğu için variant_explode, aşağıdaki örneklerdeki gibi FROM listesi içinde değil, SELECT yan tümcesinin bir parçası olarak kullanılır.
SELECT key, value
FROM store_data,
LATERAL variant_explode(store_data.raw);
SELECT pos, value
FROM store_data,
LATERAL variant_explode(store_data.raw:store.basket[0]);
Varyant türü dönüştürme kuralları
Tür kullanarak VARIANT dizileri ve skalerleri depolayabilirsiniz. Değişken türlerini diğer türlere atamaya çalışırken, normal atama kuralları aşağıdaki ek kurallarla birlikte tek tek değerler ve alanlar için geçerlidir.
Dikkat
variant_get ve try_variant_get tür bağımsız değişkenlerini alır ve bu tür dönüştürme kurallarını izler.
| Kaynak türü | Davranış |
|---|---|
VOID |
Sonuç, NULL türünde bir VARIANT'dir. |
ARRAY<elementType> |
elementType, VARIANT olarak atanabilecek bir tür olmalıdır. |
veya schema_of_variant ile schema_of_variant_agg tür çıkarılırken, çözümlenemeyen çakışan türler mevcut olduğunda, işlevler VARIANT tür yerine STRING türe geri döner.
Piton
Dönüştürme işlemi için try_variant_get işlevini (Python) kullanın.
# price is returned as a double, not a string
df_variant.select(try_variant_get(col("raw"), "$.store.bicycle.price", "double").alias("price"))
+------------------+
| price |
+------------------+
| 19.95 |
+------------------+
SQL
Dönüştürme işlemi yapmak için try_variant_get işlevini (SQL) kullanın:
-- price is returned as a double, not a string
SELECT try_variant_get(raw, '$.store.bicycle.price', 'double') as price FROM store_data
+------------------+
| price |
+------------------+
| 19.95 |
+------------------+
Desteklenen veri türlerine değerleri atamak için :: veya cast kullanabilirsiniz:
-- cast into more complex types
SELECT cast(raw:store.bicycle AS STRUCT<price DOUBLE, color STRING>) bicycle FROM store_data;
-- `::` also supported
SELECT raw:store.bicycle::STRUCT<price DOUBLE, color STRING> bicycle FROM store_data;
+------------------+
| bicycle |
+------------------+
| { |
| "price":19.95, |
| "color":"red" |
| } |
+------------------+
Dönüşüm hatalarını işlemek için try_variant_get işlevini (SQL veya Python) kullanın.
Piton
spark.range(1).select(parse_json(lit('{"a" : "c", "b" : 2}')).alias("v")).select(try_variant_get(col('v'), '$.a', 'boolean')).display()
SQL
SELECT try_variant_get(
parse_json('{"a" : "c", "b" : 2}'),
'$.a',
'boolean'
)
Değişken null kuralları
Değişken değerinin is_variant_null değişken null olup olmadığını belirlemek için işlevini (SQL veya Python) kullanın.
Piton
data = [
('null',),
(None,),
('{"field_a" : 1, "field_b" : 2}',)
]
df = spark.createDataFrame(data, ["null_data"])
df.select(parse_json(col("null_data")).alias("v")).select(is_variant_null(col("v"))).display()
+------------------+
|is_variant_null(v)|
+------------------+
| true|
+------------------+
| false|
+------------------+
| false|
+------------------+
SQL
Değişkenler iki tür null içerebilir:
-
SQL
NULL: SQLNULLs değerin eksik olduğunu gösterir. Bunlar, yapılandırılmış verilerle ilgilenirken kullanılanlarla aynıdırNULL. -
Değişken
NULL: DeğişkenNULLs, değişkenin açıkça birNULLdeğer içerdiğini gösterir. SQLNULLile aynı değildir, çünküNULLdeğeri verilerde depolanır.
SELECT
is_variant_null(parse_json(NULL)) AS sql_null,
is_variant_null(parse_json('null')) AS variant_null,
is_variant_null(parse_json('{ "field_a": null }'):field_a) AS variant_null_value,
is_variant_null(parse_json('{ "field_a": null }'):missing) AS missing_sql_value_null
+--------+------------+------------------+----------------------+
|sql_null|variant_null|variant_null_value|missing_sql_value_null|
+--------+------------+------------------+----------------------+
| false| true| true| false|
+--------+------------+------------------+----------------------+
Ek kaynaklar
-
Varyant, JSON dizelerinden nasıl farklıdır?: JSON dizesi depolamasından taşınan kullanıcılar için geçiş kılavuzu da dahil olmak üzere,
VARIANTile JSON dizeleri arasındaki karşılaştırma. -
Apache Iceberg ve Delta Lake için değişken türü desteği: Sınırlamaların
VARIANTtam listesi ve Delta'ya özgü davranışlar için.