> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-trino-dialect.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> الاستعلامات المتقدمة باستخدام ClickHouse Connect

# الاستعلامات المتقدمة

<div id="querycontexts">
  ## QueryContexts
</div>

ينفّذ ClickHouse Connect الاستعلامات القياسية ضمن `QueryContext`. يحتوي `QueryContext` على البُنى الأساسية المستخدمة لبناء الاستعلامات على قاعدة بيانات ClickHouse، بالإضافة إلى الإعدادات المستخدمة لمعالجة النتيجة وتحويلها إلى `QueryResult` أو أي بنية بيانات استجابة أخرى. ويشمل ذلك الاستعلام نفسه، والمعلمات، والإعدادات، وتنسيقات القراءة، وخصائص أخرى.

يمكن الحصول على `QueryContext` باستخدام طريقة العميل `create_query_context`. وتستقبل هذه الطريقة المعلمات نفسها التي تستقبلها طريقة الاستعلام الأساسية. ويمكن بعد ذلك تمرير سياق الاستعلام هذا إلى الطرق‏ `query` أو `query_df` أو `query_np` باعتباره وسيط الكلمة المفتاحية `context` بدلًا من أي من الوسائط الأخرى لهذه الطرق أو جميعها. لاحظ أن أي وسائط إضافية تُحدَّد عند استدعاء الطريقة ستتجاوز أي خصائص في `QueryContext`.

أوضح Use case لـ `QueryContext` هو إرسال الاستعلام نفسه مع قيم مختلفة لمَعلمات الربط. ويمكن تحديث جميع قيم المعلمات باستدعاء الطريقة ‏`QueryContext.set_parameters` باستخدام قاموس، كما يمكن تحديث أي قيمة مفردة باستدعاء `QueryContext.set_parameter` باستخدام زوج `key` و`value` المطلوب.

```python theme={null}
qc = client.create_query_context(
    query="SELECT {k:Int32}",
    parameters={"k": 13},
)
result = client.query(context=qc)
assert result.first_row == (13,)

qc.set_parameter("k", 79)
result = client.query(context=qc)
assert result.first_row == (79,)
```

لاحظ أن كائنات `QueryContext` ليست آمنة للاستخدام عبر الخيوط، ولكن يمكن الحصول على نسخة منها في بيئة متعددة الخيوط عبر استدعاء التابع `QueryContext.updated_copy`.

<div id="streaming-queries">
  ## الاستعلامات المتدفقة
</div>

يوفّر ClickHouse Connect Client عدة طرق لاسترجاع البيانات كتدفق (وهو مُنفَّذ كمُولِّد في بايثون):

* `query_column_block_stream` -- يعيد بيانات query في كتل على هيئة تسلسل من الأعمدة باستخدام كائنات بايثون الأصلية
* `query_row_block_stream` -- يعيد بيانات query على هيئة كتلة من الصفوف باستخدام كائنات بايثون الأصلية
* `query_rows_stream` -- يعيد بيانات query كتسلسل من الصفوف باستخدام كائنات بايثون الأصلية
* `query_np_stream` -- يعيد كل كتلة من بيانات query في ClickHouse كمصفوفة NumPy
* `query_df_stream` -- يعيد كل كتلة من بيانات query في ClickHouse على هيئة Pandas DataFrame
* `query_arrow_stream` -- يعيد بيانات query على هيئة كائنات PyArrow `RecordBatch`
* `query_df_arrow_stream` -- يعيد كل دفعة Arrow على هيئة Pandas DataFrame أو Polars DataFrame، ويُحدَّد ذلك بواسطة `dataframe_library`

تعيد كل طريقة كائن `StreamContext`، ويجب فتحه باستخدام عبارة `with`. وتُنتظر طرق التدفق في العميل غير المتزامن وتُفتح باستخدام `async with`.

<div id="data-blocks">
  ### كتل البيانات
</div>

يعالج ClickHouse Connect جميع البيانات القادمة من طريقة `query` الأساسية كتدفق من الكتل التي يتلقاها من خادم ClickHouse. وتُنقل هذه الكتل من ClickHouse وإليه باستخدام تنسيق "Native" المخصص. والـ"كتلة" هي ببساطة تسلسل من أعمدة البيانات الثنائية، حيث يحتوي كل عمود على عدد متساوٍ من قيم البيانات من نوع البيانات المحدد. (وبما أن ClickHouse قاعدة بيانات عمودية، فهو يخزّن هذه البيانات بصيغة مشابهة.) ويتحكم في حجم الكتلة المُعادة من الاستعلام إعدادان للمستخدم يمكن ضبطهما على عدة مستويات (ملف تعريف المستخدم، أو المستخدم، أو الجلسة، أو الاستعلام). وهما:

* [max\_block\_size](/ar/reference/settings/session-settings#max_block_size) -- الحد الأقصى لحجم الكتلة بالصفوف.
* [preferred\_block\_size\_bytes](/ar/reference/settings/session-settings#preferred_block_size_bytes) -- حجم الكتلة المفضّل بالبايت.

بغض النظر عن `preferred_block_size_bytes`، لن تتجاوز أي كتلة أبدًا `max_block_size` صفًا. وقد يكون الحجم الفعلي أصغر، ويجب عدم اعتباره ثابتًا.

عند استخدام إحدى طرائق Client `query_*_stream`، تُعاد النتائج كتلةً بكتلة. ولا يحمّل ClickHouse Connect سوى كتلة واحدة في كل مرة. ويتيح ذلك معالجة كميات كبيرة من البيانات دون الحاجة إلى تحميل مجموعة نتائج كبيرة كاملةً إلى الذاكرة. لاحظ أنه ينبغي أن يكون التطبيق مستعدًا لمعالجة أي عدد من الكتل، ولا يمكن التحكم في الحجم الدقيق لكل كتلة.

<div id="http-data-buffer-for-slow-processing">
  ### مخزن بيانات HTTP المؤقت عند بطء المعالجة
</div>

إذا كان أحد التطبيقات يستهلك الكتل بمعدل أبطأ بكثير من معدل إنتاجها من الخادم، فقد يُغلَق اتصال HTTP قبل اكتمال المعالجة. زِد الإعداد العام `http_buffer_size` عندما تتوفر للتطبيق ذاكرة كافية لتخزين المزيد من بيانات الاستجابة مؤقتًا. القيمة الافتراضية هي 10 MiB. تظل بايتات الاستجابة `lz4` و`zstd` مضغوطة داخل هذا المخزن المؤقت، مما يزيد من سعته الفعلية.

<div id="streamcontexts">
  ### StreamContexts
</div>

تعيد كل واحدة من طرق `query_*_stream` (مثل `query_row_block_stream`) كائن `StreamContext` من ClickHouse، وهو كائن مدمج يجمع بين السياق والمولِّد في بايثون. وهذا هو الاستخدام الأساسي:

```python theme={null}
with client.query_row_block_stream(
    "SELECT pickup, dropoff, pickup_longitude, pickup_latitude FROM taxi_trips"
) as stream:
    for block in stream:
        for row in block:
            process_trip(row)
```

لاحظ أن محاولة استخدام `StreamContext` من دون تعليمة `with` ستؤدي إلى حدوث خطأ. ويضمن استخدام سياق بايثون إغلاق التدفق (في هذه الحالة، استجابة HTTP متدفقة) بشكل صحيح حتى إذا لم تُستهلك جميع البيانات و/أو حدث استثناء أثناء المعالجة. كذلك، لا يمكن استخدام `StreamContext` لاستهلاك التدفق إلا مرة واحدة. وستؤدي محاولة استخدام `StreamContext` بعد الخروج منه إلى ظهور `StreamClosedError`.

إذا فشل الاتصال أثناء قراءة نتيجة، فسيُطلق `StreamFailureError` بدلًا من إعادة نتيجة مقتطعة بصمت. وتتبع رسالته إعداد `show_clickhouse_errors` الخاص بالعميل.

يمكنك استخدام الخاصية `source` في `StreamContext` للوصول إلى الكائن الأب للنتيجة، الذي يتضمن أسماء الأعمدة وأنواعها. وبالنسبة إلى معظم التدفقات، يكون هذا الكائن `QueryResult`؛ أما الطريقتان `query_np_stream` و`query_df_stream` فتُظهران بدلًا من ذلك `NumpyResult`.

<div id="stream-types">
  ### أنواع التدفق
</div>

تعيد الطريقة `query_column_block_stream` الكتلة كتسلسل من بيانات الأعمدة المخزَّنة على هيئة أنواع بيانات بايثون الأصلية. وباستخدام استعلامات `taxi_trips` أعلاه، ستكون البيانات المعادة قائمةً يكون كل عنصر فيها قائمةً أخرى (أو `tuple`) تضم كل البيانات الخاصة بالعمود المقابل. لذا فإن `block[0]` سيكون `tuple` لا يحتوي إلا على سلاسل نصية. وتُستخدم التنسيقات المعتمدة على الأعمدة غالبًا لإجراء عمليات تجميعية على جميع القيم في عمود معيّن، مثل جمع إجمالي الأجور.

تعيد الطريقة `query_row_block_stream` الكتلة كتسلسل من الصفوف، كما في قواعد البيانات العلائقية التقليدية. وبالنسبة إلى رحلات التاكسي، ستكون البيانات المعادة قائمةً يكون كل عنصر فيها قائمةً أخرى تمثل صفًا من البيانات. لذا فإن `block[0]` سيحتوي على جميع الحقول بالترتيب لأول رحلة تاكسي، و`block[1]` سيحتوي على صف يضم جميع الحقول الخاصة برحلة التاكسي الثانية، وهكذا. وتُستخدم النتائج المعتمدة على الصفوف عادةً لأغراض العرض أو عمليات التحويل.

تنتقل الطريقة `query_rows_stream` تلقائيًا إلى الكتلة التالية وتُنتج صفًا واحدًا في كل مرة. وهي النظير صفًا بصفّ للطريقة `query_row_block_stream`.

تعيد الطريقة `query_np_stream` كل كتلة على شكل مصفوفة NumPy. وعندما تشترك جميع أعمدة النتائج في نوع بيانات NumPy نفسه (`dtype`)، تكون المصفوفة ثنائية الأبعاد بالشكل `(rows, columns)`. أما النتائج المختلطة فتُعاد على هيئة مصفوفة مهيكلة أحادية البعد أو باستخدام نوع البيانات `object`.

تعيد الطريقة `query_df_stream` كل كتلة ClickHouse على شكل Pandas DataFrame ثنائية الأبعاد. إليك مثالًا يوضّح أنه يمكن استخدام الكائن `StreamContext` كسياق بصورة مؤجلة (ولكن مرة واحدة فقط).

```python theme={null}
df_stream = client.query_df_stream("SELECT * FROM hits")
column_names = df_stream.source.column_names
with df_stream:
    for df in df_stream:
        process_dataframe(df)
```

تحوّل الطريقة `query_df_arrow_stream` دفعات Arrow إلى DataFrame من Pandas أو Polars. حدِّد المكتبة باستخدام `dataframe_library`، وقيمتها الافتراضية `"pandas"`.

أخيرًا، تُغلِّف `query_arrow_stream` استجابة ClickHouse `ArrowStream` داخل `StreamContext`. ويُرجِع كل تكرار `RecordBatch` من PyArrow.

<div id="streaming-examples">
  ### أمثلة على البيانات المتدفقة
</div>

<div id="stream-rows">
  #### تدفّق الصفوف
</div>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Stream large result sets row by row
with client.query_rows_stream("SELECT number, number * 2 as doubled FROM system.numbers LIMIT 100000") as stream:
    for row in stream:
        print(row)  # Process each row
        # Output:
        # (0, 0)
        # (1, 2)
        # (2, 4)
        # Additional rows follow
```

<div id="stream-row-blocks">
  #### تدفق كتل الصفوف
</div>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Stream in blocks of rows (more efficient than row-by-row)
with client.query_row_block_stream("SELECT number, number * 2 FROM system.numbers LIMIT 100000") as stream:
    for block in stream:
        print(f"Received block with {len(block)} rows")
```

<div id="stream-pandas-dataframes">
  #### تدفق Pandas DataFrames
</div>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Stream query results as Pandas DataFrames
with client.query_df_stream("SELECT number, toString(number) AS str FROM system.numbers LIMIT 100000") as stream:
    for df in stream:
        # Process each DataFrame block
        print(f"Received DataFrame with {len(df)} rows")
        print(df.head(3))
```

<div id="stream-arrow-batches">
  #### تدفق دفعات Arrow
</div>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Stream query results as Arrow record batches
with client.query_arrow_stream("SELECT * FROM large_table") as stream:
    for arrow_batch in stream:
        # Process each Arrow batch
        print(f"Received Arrow batch with {arrow_batch.num_rows} rows")
```

<div id="async-stream-rows">
  #### صفوف التدفق غير المتزامنة
</div>

```python theme={null}
import asyncio

import clickhouse_connect


async def main():
    async_client = await clickhouse_connect.get_async_client()
    async with await async_client.query_rows_stream(
        "SELECT number FROM numbers(100000)"
    ) as stream:
        async for row in stream:
            print(row)


asyncio.run(main())
```

<div id="numpy-pandas-and-arrow-queries">
  ## استعلامات NumPy وPandas وArrow
</div>

يوفّر ClickHouse Connect طرق استعلام متخصصة للعمل مع هياكل بيانات NumPy وPandas وArrow. وتتيح لك هذه الطرق استرجاع نتائج الاستعلام مباشرةً بهذه التنسيقات الشائعة للبيانات من دون تحويل يدوي.

<div id="numpy-queries">
  ### استعلامات NumPy
</div>

تعيد الطريقة `query_np` نتائج الاستعلام على شكل مصفوفة NumPy بدلًا من كائن `QueryResult` في ClickHouse Connect.

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Query returns a NumPy array
np_array = client.query_np("SELECT number, number * 2 AS doubled FROM system.numbers LIMIT 5")

print(type(np_array))
# Output:
# <class 'numpy.ndarray'>

print(np_array)
# Output:
# [[0 0]
#  [1 2]
#  [2 4]
#  [3 6]
#  [4 8]]
```

<div id="pandas-queries">
  ### استعلامات Pandas
</div>

تعيد الدالة `query_df` نتائج الاستعلام في صورة Pandas DataFrame بدلًا من `QueryResult` في ClickHouse Connect.

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Query returns a Pandas DataFrame
df = client.query_df("SELECT number, number * 2 AS doubled FROM system.numbers LIMIT 5")

print(type(df))
# Output: <class 'pandas.core.frame.DataFrame'>
print(df)
# Output:
#    number  doubled
# 0       0        0
# 1       1        2
# 2       2        4
# 3       3        6
# 4       4        8
```

<div id="pyarrow-queries">
  ### استعلامات PyArrow
</div>

تعيد الدالة `query_arrow` جدول PyArrow باستخدام تنسيق الإخراج `Arrow` في ClickHouse مباشرةً. وهي تقبل `query` و`parameters` و`settings` و`external_data` و`transport_settings`. ويتحكم الخيار `use_strings` في ما إذا كانت أعمدة ClickHouse من النوع `String` ستُخرَج كسلاسل نصية في Arrow أو كقيم ثنائية.

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Query returns a PyArrow Table
arrow_table = client.query_arrow("SELECT number, toString(number) AS str FROM system.numbers LIMIT 3")

print(type(arrow_table))
# Output:
# <class 'pyarrow.lib.Table'>

print(arrow_table)
# Output:
# pyarrow.Table
# number: uint64 not null
# str: string not null
# ----
# number: [[0,1,2]]
# str: [["0","1","2"]]
```

<div id="arrow-backed-dataframes">
  ### DataFrames المستندة إلى Arrow
</div>

يدعم ClickHouse Connect إنشاء DataFrame بكفاءة من نتائج Arrow من خلال `query_df_arrow` و`query_df_arrow_stream`. تتجنب هاتان الطريقتان التحويل عبر كائنات الصفوف في بايثون، وتعيدان استخدام مخازن Arrow المؤقتة عندما تسمح بذلك المكتبة المستهدفة:

* `query_df_arrow`: ينفّذ الاستعلام باستخدام تنسيق الإخراج `Arrow` في ClickHouse ويُرجع DataFrame.
  * `dataframe_library="pandas"` يُرجع DataFrame من Pandas 2.0 أو إصدار أحدث باستخدام `pd.ArrowDtype`.
  * `dataframe_library="polars"` يُرجع DataFrame من Polars مُنشأً عبر `pl.from_arrow`.
* `query_df_arrow_stream`: يبث دفعات Arrow على شكل DataFrames من Pandas أو Polars.

<div id="query-to-arrow-backed-dataframe">
  #### من الاستعلام إلى DataFrame مستند إلى Arrow
</div>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Query returns a Pandas DataFrame with Arrow dtypes (requires pandas 2.x)
df = client.query_df_arrow(
    "SELECT number, toString(number) AS str FROM system.numbers LIMIT 3",
    dataframe_library="pandas"
)

print(df.dtypes)
# Output:
# number    uint64[pyarrow]
# str       string[pyarrow]
# dtype: object

# Or use Polars
polars_df = client.query_df_arrow(
    "SELECT number, toString(number) AS str FROM system.numbers LIMIT 3",
    dataframe_library="polars"
)
print(polars_df.dtypes)
# Output:
# [UInt64, String]

# Streaming into batches of DataFrames (polars shown)
with client.query_df_arrow_stream(
    "SELECT number, toString(number) AS str FROM system.numbers LIMIT 100000", dataframe_library="polars"
) as stream:
    for df_batch in stream:
        print(f"Received {type(df_batch)} batch with {len(df_batch)} rows and dtypes: {df_batch.dtypes}")
```

<div id="notes-and-caveats">
  #### ملاحظات ومحاذير
</div>

* يتحكم ClickHouse في مخطط Arrow. ويمكن إرجاع الأنواع التي لا تملك تمثيلًا مباشرًا في Arrow باستخدام نوع فعلي متوافق، بما في ذلك الحقول الثنائية. افحص `table.schema` أو أنواع بيانات DataFrame قبل تطبيق التحويلات الخاصة بالتطبيق.
* تتطلب نتائج Pandas المستندة إلى Arrow الإصدار 2.0 من Pandas أو أحدث.
* يتحكم `use_strings` في ما إذا كانت أعمدة ClickHouse `String` تستخدم حقول Arrow النصية أم الثنائية عندما يدعم الخادم `output_format_arrow_string_as_string`.
* لا تزال `tz_mode="schema"` غير مدعومة في طرق الاستعلام المستندة إلى Arrow. وهي تصدر تحذيرًا وتحافظ على البيانات الوصفية للمنطقة الزمنية التي يوفّرها رد Arrow.

<div id="read-formats">
  ## تنسيقات القراءة
</div>

تتحكم تنسيقات القراءة في القيم المُعادة من `query` و`query_np` و`query_df`. ولا تنطبق على الأساليب الخام أو أساليب Arrow، لأن هذه الأساليب تستخدم تنسيق إخراج الخادم مباشرةً. على سبيل المثال، يؤدي تعيين تنسيق قراءة معرّف UUID إلى `"string"` إلى إرجاع سلاسل UUID بدلًا من كائنات `uuid.UUID`.

يمكن أن تتضمن وسيطة "نوع البيانات" لأي دالة تنسيق أحرف بدل. ويكون التنسيق سلسلة واحدة بأحرف صغيرة. وتحافظ المغلّفات الحاوية مثل `Array` و`Nullable` و`LowCardinality` على التنسيق المحدد لنوع العنصر فيها.

يمكن تعيين تنسيقات القراءة على عدة مستويات:

* على المستوى العام، باستخدام الأساليب المعرّفة في الحزمة `clickhouse_connect.datatypes.format`. وسيتحكم ذلك في تنسيق نوع البيانات المُعَدّ لجميع الاستعلامات.

```python theme={null}
from clickhouse_connect.datatypes.format import set_read_format

# Return both IPv6 and IPv4 values as strings
set_read_format("IPv*", "string")

# Return all Date types as the underlying epoch second or epoch day
set_read_format("Date*", "int")
```

* على مستوى الاستعلام بأكمله، باستخدام وسيطة القاموس الاختيارية `query_formats`. في هذه الحالة، سيستخدم أي عمود (أو عمود فرعي) من أنواع البيانات المحددة التنسيق المُهيّأ.

```python theme={null}
# Return any UUID column as a string
client.query(
    "SELECT user_id, user_uuid, device_uuid FROM users",
    query_formats={"UUID": "string"},
)
```

* لعمود نتيجة معيّن، استخدم القاموس الاختياري `column_formats`. يمثّل كل مفتاح اسم عمود مُعاد، وتمثّل قيمته سلسلة تنسيق أو تعيينًا متداخلًا من أسماء أنواع ClickHouse إلى التنسيقات، وهذا مفيد مع Tuples وMaps وغيرها من أنواع الحاويات.

```python theme={null}
# Return IPv6 values in the `dev_address` column as strings
client.query(
    "SELECT device_id, dev_address, gw_address FROM devices",
    column_formats={"dev_address": "string"},
)
```

<div id="read-format-options-python-types">
  ### خيارات تنسيق القراءة (أنواع بايثون)
</div>

| نوع ClickHouse          | نوع بايثون الأصلي       | تنسيقات القراءة   | التعليقات                                                                                                 |
| ----------------------- | ----------------------- | ----------------- | --------------------------------------------------------------------------------------------------------- |
| Int\[8-64], UInt\[8-32] | int                     | string            |                                                                                                           |
| UInt64                  | int                     | signed            | لا يتعامل Superset حاليًا مع قيم UInt64 غير الموقعة الكبيرة                                               |
| \[U]Int\[128,256]       | int                     | string            | قيم int في Pandas وNumPy بحد أقصى 64 بت، لذا يمكن إرجاع هذه القيم كسلاسل نصية                             |
| BFloat16                | float                   | -                 | جميع قيم float في بايثون تكون داخليًا بدقة 64 بت                                                          |
| Float32                 | float                   | string            | جميع قيم float في بايثون تكون داخليًا بدقة 64 بت                                                          |
| Float64                 | float                   | string            |                                                                                                           |
| Decimal                 | decimal.Decimal         | -                 |                                                                                                           |
| String                  | str                     | bytes             | لا تحتوي أعمدة String في ClickHouse على ترميز أصيل، لذا تُستخدم أيضًا للبيانات الثنائية ذات الطول المتغير |
| FixedString             | bytes                   | string            | FixedStrings هي مصفوفات بايتات ذات حجم ثابت، لكنها تُعامل أحيانًا كسلاسل نصية في بايثون                   |
| Enum\[8,16]             | str                     | int               | يعيد التنسيق الأصلي التسميات؛ بينما يعيد `int` القيمة الصحيحة الأساسية.                                   |
| Date                    | datetime.date           | int               | يعيد التنسيق العددي عدد الأيام منذ 1970-01-01.                                                            |
| Date32                  | datetime.date           | int               | يعيد التنسيق العددي إزاحة الأيام الموقعة الأوسع.                                                          |
| DateTime                | datetime.datetime       | int               | يعيد التنسيق العددي ثواني epoch.                                                                          |
| DateTime64              | datetime.datetime       | int               | يعيد التنسيق العددي قيم tick وفق precision العمود. تقتصر `datetime` في بايثون على الميكروثواني.           |
| Time                    | datetime.timedelta      | int, string, time | يعيد التنسيق العددي الثواني. يقتصر تنسيق `time` على القيم التي تتوافق مع `datetime.time`.                 |
| Time64                  | datetime.timedelta      | int, string, time | يعيد التنسيق العددي قيم tick وفق precision العمود. تقتصر `timedelta` في بايثون على الميكروثواني.          |
| IPv4                    | `ipaddress.IPv4Address` | string, int       | يمكن قراءة عناوين IP كسلاسل نصية أو كأعداد صحيحة.                                                         |
| IPv6                    | `ipaddress.IPv6Address` | string            | يمكن قراءة عناوين IP كسلاسل نصية، وإذا كانت منسقة بشكل صحيح فيمكن إدراجها كعناوين IP                      |
| Tuple                   | dict or tuple           | tuple, dict, json | تعيد Tuples المسماة قواميس افتراضيًا؛ بينما تعيد Tuples غير المسماة tuples.                               |
| Map                     | dict                    | -                 |                                                                                                           |
| Nested                  | Sequence\[dict]         | -                 |                                                                                                           |
| UUID                    | uuid.UUID               | string            | يمكن قراءة UUIDs كسلاسل نصية منسقة وفق RFC 4122<br />                                                     |
| JSON                    | dict                    | string            | يُرجع قاموس بايثون افتراضيًا. ويُرجع تنسيق `string` JSON string                                           |
| Variant                 | object                  | typed             | يُرجع `typed` القيمة `TypedVariant(value, type_name)` بحيث يُحفَظ نوع العضو الأصلي.                       |
| Dynamic                 | object                  | -                 | يعيد نوع بايثون المطابق لنوع بيانات ClickHouse المخزَّن لهذه القيمة                                       |
| QBit                    | list\[float]            | -                 | يُستخدم NumPy تلقائيًا لتسريع تبديل مواضع البتات عند تثبيته.                                              |

<div id="external-data">
  ## البيانات الخارجية
</div>

يمكن لاستعلامات ClickHouse قبول بيانات خارجية بأي تنسيق إدخال مدعوم. يرسل العميل البيانات كجزء من الطلب، ويمكن للاستعلام الرجوع إليها باعتبارها جدولًا خارجيًا مؤقتًا. راجع [توثيق البيانات الخارجية في ClickHouse](/ar/reference/engines/table-engines/special/external-data). تقبل طرائق استعلام العميل كائن `clickhouse_connect.driver.external.ExternalData` عبر المعلمة `external_data`.

| الاسم      | النوع             | الوصف                                                                                                                                   |
| ---------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| file\_path | str               | مسار ملف على النظام المحلي لقراءة البيانات الخارجية منه. يجب توفير `file_path` أو `data`                                                |
| file\_name | str               | اسم "ملف" البيانات الخارجية. إذا لم يتم توفيره، فسيُؤخذ من جزء اسم الملف في `file_path`. اسم الجدول الخارجي هو اسم الملف من دون امتداده |
| data       | bytes             | البيانات الخارجية بصيغة ثنائية (بدلًا من قراءتها من ملف). يجب توفير `data` أو `file_path`                                               |
| fmt        | str               | [تنسيق الإدخال](/ar/reference/formats) للبيانات في ClickHouse. القيمة الافتراضية هي `TSV`                                               |
| types      | str or seq of str | قائمة بأنواع بيانات الأعمدة في البيانات الخارجية. إذا كانت سلسلة نصية، فيجب فصل الأنواع بفواصل. يجب توفير `types` أو `structure`        |
| structure  | str or seq of str | قائمة بأسماء الأعمدة + أنواع البيانات في البيانات (راجع الأمثلة). يجب توفير `structure` أو `types`                                      |
| mime\_type | str               | نوع MIME اختياري لبيانات الملف. يتجاهل ClickHouse حاليًا هذا الترويس الفرعي في HTTP                                                     |

يوضح هذا المثال ربط ملف CSV خارجي بجدول `directors` مخزَّن على الخادم:

```python theme={null}
import clickhouse_connect
from clickhouse_connect.driver.external import ExternalData

client = clickhouse_connect.get_client()
ext_data = ExternalData(
    file_path="/data/movies.csv",
    fmt="CSV",
    structure=[
        "movie String",
        "year UInt16",
        "rating Decimal32(3)",
        "director String",
    ],
)
result = client.query(
    "SELECT name, avg(rating) "
    "FROM directors INNER JOIN movies ON directors.name = movies.director "
    "GROUP BY directors.name",
    external_data=ext_data,
).result_rows
```

يمكن إضافة ملفات بيانات خارجية إضافية إلى الكائن `ExternalData` الأساسي باستخدام الطريقة `add_file`، التي تأخذ المعاملات نفسها التي يأخذها المُنشئ. بالنسبة إلى HTTP، تُرسَل جميع البيانات الخارجية كجزء من تحميل ملف `multi-part/form-data`.

لا تدعم الواجهة الخلفية لـ chDB البيانات الخارجية.

<div id="time-zones">
  ## المناطق الزمنية
</div>

تُنقل قيم `DateTime` و`DateTime64` في ClickHouse على هيئة قيم رقمية مستندة إلى epoch. ويحوّلها ClickHouse Connect إلى كائنات `datetime` في بايثون باستخدام البيانات الوصفية للأعمدة، وتجاوزات الاستعلام، وسياسة المنطقة الزمنية الخاصة بالعميل.

لدى العميل خياران مستقلان للمنطقة الزمنية:

* يحدّد `tz_source` المنطقة الزمنية الاحتياطية للأعمدة التي لا تحتوي على بيانات وصفية صريحة للمنطقة الزمنية:
  * `"auto"` هو الخيار الافتراضي. ويستخدم المنطقة الزمنية للخادم عندما يتمكن العميل من تحديدها بأمان عبر انتقالات التوقيت الصيفي، وإلا يستخدم المنطقة الزمنية المحلية.
  * تستخدم `"server"` دائماً المنطقة الزمنية للخادم.
  * تستخدم `"local"` دائماً المنطقة الزمنية المحلية للعملية.
* يحدّد `tz_mode` كيفية التعامل مع معلومات المنطقة الزمنية:
  * `"naive_utc"` هو الخيار الافتراضي. وتُعاد النتائج ذات التوقيت UTC أو المكافئ له على هيئة كائنات `datetime` غير مرتبطة بمنطقة زمنية، حفاظاً على التوافق مع الإصدارات السابقة.
  * تحافظ `"aware"` على `tzinfo` الخاصة بـ UTC وتعيد قيماً مرتبطة بمنطقة زمنية بتوقيت UTC.
  * تعيد `"schema"` قيماً مرتبطة بمنطقة زمنية فقط عندما يصرّح نوع العمود بمنطقة زمنية، وتعيد قيماً غير مرتبطة بمنطقة زمنية لأعمدة `DateTime`/`DateTime64` المجرّدة.

في الاستعلامات العادية `"naive_utc"` و`"aware"`، تُحدَّد المنطقة الزمنية النشطة بهذا الترتيب:

1. تجاوز `column_tzs` لكل عمود.
2. البيانات الوصفية للمنطقة الزمنية في نوع عمود ClickHouse.
3. تجاوز `query_tz` على مستوى الاستعلام.
4. معلومات المنطقة الزمنية المُعادة مع استجابة HTTP.
5. المنطقة الزمنية الاحتياطية التي يحددها `tz_source`.

يتجاهل `tz_mode="schema"` المناطق الزمنية الخاصة بالاستعلام والمناطق الزمنية الاحتياطية، لكن تجاوز `column_tzs` الصريح يظل ذا أولوية.

```python theme={null}
result = client.query(
    "SELECT "
    "toDateTime('2026-01-15 12:00:00', 'UTC') AS utc_time, "
    "toDateTime('2026-01-15 12:00:00', 'America/Denver') AS denver_time",
    tz_mode="aware",
)

assert result.first_row[0].tzinfo is not None
assert result.first_row[1].tzinfo is not None
```

تُحدَّد أسماء المناطق الزمنية باستخدام وحدة `zoneinfo` من المكتبة القياسية. تتلقى عمليات تثبيت Windows حزمة `tzdata` تلقائيًا. في صور Linux المصغّرة التي لا تتضمن قاعدة بيانات IANA للمناطق الزمنية، ثبّت `clickhouse-connect[tzdata]`.

تحافظ نتائج Pandas على الدقة الطبيعية لكل نوع في ClickHouse، مثل `datetime64[s]` لـ `DateTime` و`datetime64[ms]` لـ `DateTime64(3)`. لا تدعم طريقتا DataFrame المعتمدتان على Arrow، `query_df_arrow` و`query_df_arrow_stream`، الخيار `tz_mode="schema"` بعد، وستصدران تحذيرًا عند طلبه. وتُرجع `query_arrow` و`query_arrow_stream` البيانات الوصفية للمنطقة الزمنية من استجابة Arrow كما هي.
