الانتقال إلى المحتوى الرئيسي

واجهة برمجة التطبيقات الخام

لحالات الاستخدام التي لا تتطلب تحويلًا بين بيانات ClickHouse وأنواع البيانات والبُنى الأصلية أو الخاصة بجهات خارجية، يوفّر عميل ClickHouse Connect طرقًا لاستخدام اتصال ClickHouse مباشرةً.

الطريقة raw_query في Client

تتيح الطريقة Client.raw_query استخدام واجهة استعلام HTTP الخاصة بـ ClickHouse مباشرةً عبر اتصال العميل. وتكون القيمة المُعادة كائن bytes غير مُعالَج. كما توفّر طبقة تغليف ملائمة مع ربط المعلمات، ومعالجة الأخطاء، وإعادات المحاولة، وإدارة الإعدادات من خلال واجهة مبسطة:
ParameterTypeDefaultDescription
querystrRequiredأي استعلام ClickHouse صالح
parametersdict or iterableNoneراجع وصف المعلمات.
settingsdictNoneراجع وصف الإعدادات.
fmtstrNoneتنسيق الإخراج في ClickHouse للبايتات الناتجة. (يستخدم ClickHouse تنسيق TSV إذا لم يتم تحديده)
use_databaseboolTrueاستخدم قاعدة البيانات المعيّنة من عميل ClickHouse Connect لسياق الاستعلام
external_dataExternalDataNoneكائن ExternalData يحتوي على بيانات ملف أو بيانات binary لاستخدامها مع الاستعلام. راجع الاستعلامات المتقدمة (البيانات الخارجية)
تقع على عاتق المستدعي مسؤولية التعامل مع كائن bytes الناتج. لاحظ أن Client.query_arrow ليس سوى طبقة تغليف خفيفة حول هذه الطريقة باستخدام تنسيق الإخراج Arrow في ClickHouse.

طريقة raw_stream في Client

توفّر الطريقة Client.raw_stream واجهة برمجة تطبيقات مماثلة للطريقة raw_query، لكنها تُرجع كائن io.IOBase يمكن استخدامه كمصدر تدفق/مولّد لكائنات bytes. وتُستخدم حاليًا في الطريقة query_arrow_stream.

طريقة raw_insert في Client

تتيح الطريقة Client.raw_insert إجراء عمليات إدراج مباشرة لكائنات bytes أو مولدات كائنات bytes باستخدام اتصال العميل. ونظرًا لأنها لا تجري أي معالجة لحمولة الإدراج، فهي عالية الكفاءة جدًا. كما توفّر الطريقة خيارات لتحديد الإعدادات وتنسيق الإدراج:
المعلمةالنوعالافتراضيالوصف
tablestrRequiredاسم الجدول البسيط أو اسم الجدول الكامل متضمّنًا اسم قاعدة البيانات
column_namesSequence[str]Noneأسماء الأعمدة الخاصة بكتلة الإدراج. وهي مطلوبة إذا كانت المعلمة fmt لا تتضمن الأسماء
insert_blockstr, bytes, Generator[bytes], BinaryIORequiredالبيانات المطلوب إدراجها. سيتم ترميز السلاسل النصية باستخدام ترميز العميل.
settingsdictNoneراجع وصف الإعدادات.
fmtstrNoneتنسيق الإدخال في ClickHouse لبايتات insert_block. (يستخدم ClickHouse تنسيق TSV إذا لم يُحدَّد)
تقع على عاتق المستدعي مسؤولية التأكد من أن insert_block بالتنسيق المحدد ويستخدم طريقة الضغط المحددة. ويستخدم ClickHouse Connect عمليات الإدراج الخام هذه لرفع الملفات وجداول PyArrow، مع تفويض التحليل إلى خادم ClickHouse.

حفظ نتائج الاستعلامات كملفات

يمكنك بث الملفات مباشرةً من ClickHouse إلى نظام الملفات المحلي باستخدام الطريقة raw_stream. على سبيل المثال، إذا كنت ترغب في حفظ نتائج استعلام في ملف CSV، فيمكنك استخدام مقتطف الشيفرة التالي:
import clickhouse_connect

if __name__ == '__main__':
    client = clickhouse_connect.get_client()
    query = 'SELECT number, toString(number) AS number_as_str FROM system.numbers LIMIT 5'
    fmt = 'CSVWithNames'  # or CSV, or CSVWithNamesAndTypes, or TabSeparated, etc.
    stream = client.raw_stream(query=query, fmt=fmt)
    with open("output.csv", "wb") as f:
        for chunk in stream:
            f.write(chunk)
ينتج عن الشيفرة أعلاه ملف output.csv بالمحتوى التالي:
"number","number_as_str"
0,"0"
1,"1"
2,"2"
3,"3"
4,"4"
وبالمثل، يمكنك حفظ البيانات بتنسيق TabSeparated وبتنسيقات أخرى. راجع تنسيقات بيانات الإدخال والإخراج للاطلاع على نظرة عامة على جميع خيارات التنسيق المتاحة.

حالات الاستخدام متعددة الخيوط، ومتعددة العمليات، وغير المتزامنة/القائمة على حلقة الأحداث

يعمل ClickHouse Connect بكفاءة في التطبيقات متعددة الخيوط، ومتعددة العمليات، والتطبيقات غير المتزامنة/القائمة على حلقة الأحداث. تتم جميع عمليات معالجة الاستعلامات والإدراج ضمن خيط واحد، لذا تكون العمليات آمنة على مستوى الخيوط بشكل عام. (قد تُضاف مستقبلًا إمكانية المعالجة المتوازية لبعض العمليات على مستوى منخفض لتجاوز أثر الأداء المترتب على الاعتماد على خيط واحد، ولكن حتى في هذه الحالة ستظل السلامة على مستوى الخيوط محفوظة.) ولأن كل استعلام أو عملية إدراج يتم تنفيذها يحتفظ كلٌّ منها بحالته داخل الكائن QueryContext أو InsertContext الخاص به، على التوالي، فإن هذه الكائنات المساعدة ليست آمنة على مستوى الخيوط، ولا ينبغي مشاركتها بين عدة تدفقات معالجة. راجع أيضًا المناقشة الإضافية حول كائنات السياق في قسمي QueryContexts وInsertContexts. إضافةً إلى ذلك، في التطبيق الذي توجد فيه استعلامات و/أو عمليات إدراج، اثنتان أو أكثر، “قيد التنفيذ” في الوقت نفسه، هناك اعتباران إضافيان ينبغي أخذهما في الحسبان. الأول هو “الجلسة” في ClickHouse المرتبطة بالاستعلام/الإدراج، والثاني هو تجمع اتصالات HTTP الذي تستخدمه مثيلات ClickHouse Connect Client.

طبقة تغليف AsyncClient

يوفّر ClickHouse Connect طبقة تغليف غير متزامنة فوق Client العادي، مما يتيح استخدام العميل في بيئة asyncio. للحصول على مثيل من AsyncClient، يمكنك استخدام دالة المصنع get_async_client، التي تقبل المعلمات نفسها التي تقبلها get_client القياسية:
import asyncio

import clickhouse_connect

async def main():
    client = await clickhouse_connect.get_async_client()
    result = await client.query("SELECT name FROM system.databases LIMIT 1")
    print(result.result_rows)
    # Output:
    # [('INFORMATION_SCHEMA',)]

asyncio.run(main())
يمتلك AsyncClient نفس الطرق وبنفس المعاملات مثل Client القياسي، لكنها تكون coroutines حيثما ينطبق ذلك. داخليًا، تُغلَّف الطرق في Client التي تُجري عمليات I/O داخل استدعاء run_in_executor. سيتحسن الأداء متعدد الخيوط عند استخدام طبقة تغليف AsyncClient، إذ سيُحرَّر كلٌّ من خيوط التنفيذ وGIL أثناء انتظار اكتمال عمليات I/O. ملاحظة: بخلاف Client العادي، يفرض AsyncClient تعيين autogenerate_session_id إلى False افتراضيًا. راجع أيضًا: مثال run_async.

إدارة معرّفات الجلسات في ClickHouse

يُنفَّذ كل استعلام في ClickHouse ضمن سياق “جلسة” في ClickHouse. وتُستخدم الجلسات حاليًا لغرضين: بشكل افتراضي، يستخدم كل استعلام يُنفَّذ بواسطة مثيل Client من ClickHouse Connect معرّف الجلسة الخاص بذلك العميل. تعمل عبارات SET والجداول المؤقتة كما هو متوقع عند استخدام عميل واحد. ومع ذلك، لا يسمح خادم ClickHouse بتنفيذ استعلامات متزامنة ضمن الجلسة نفسها (وسيرفع العميل الخطأ ProgrammingError إذا جرت محاولة ذلك). بالنسبة إلى التطبيقات التي تنفّذ استعلامات متزامنة، استخدم أحد الأنماط التالية:
  1. أنشئ مثيل Client منفصلًا لكل thread/process/event handler يحتاج إلى عزل للجلسة. يحافظ ذلك على حالة الجلسة الخاصة بكل عميل (الجداول المؤقتة وقيم SET).
  2. استخدم session_id فريدًا لكل استعلام عبر الوسيط settings عند استدعاء query أو command أو insert، إذا لم تكن بحاجة إلى حالة جلسة مشتركة.
  3. عطّل الجلسات على عميل مشترك عبر تعيين autogenerate_session_id=False قبل إنشاء العميل (أو مرّره مباشرةً إلى get_client).
from clickhouse_connect import common
import clickhouse_connect

common.set_setting('autogenerate_session_id', False)  # This should always be set before creating a client
client = clickhouse_connect.get_client(host='somehost.com', user='dbuser', password=1234)
بدلًا من ذلك، مرّر autogenerate_session_id=False مباشرةً إلى get_client(...). في هذه الحالة، لا يرسل ClickHouse Connect قيمة session_id؛ ولا يعتبر الخادم الطلبات المنفصلة جزءًا من الجلسة نفسها. ولن تستمر الجداول المؤقتة وإعدادات مستوى الجلسة عبر الطلبات.

تخصيص مجمع اتصالات HTTP

يستخدم ClickHouse Connect مجمعات اتصالات urllib3 لإدارة اتصال HTTP الأساسي مع الخادم. افتراضيًا، تشترك جميع مثيلات العميل في مجمع الاتصالات نفسه، وهو كافٍ لمعظم حالات الاستخدام. ويحافظ هذا المجمع الافتراضي على ما يصل إلى 8 اتصالات HTTP Keep Alive مع كل خادم ClickHouse يستخدمه التطبيق. بالنسبة إلى التطبيقات الكبيرة متعددة الخيوط، قد يكون من الأنسب استخدام مجمعات اتصالات منفصلة. ويمكن توفير مجمعات اتصالات مخصّصة عبر وسيط الكلمة المفتاحية pool_mgr للدالة الرئيسية clickhouse_connect.get_client:
import clickhouse_connect
from clickhouse_connect.driver import httputil

big_pool_mgr = httputil.get_pool_manager(maxsize=16, num_pools=12)

client1 = clickhouse_connect.get_client(pool_mgr=big_pool_mgr)
client2 = clickhouse_connect.get_client(pool_mgr=big_pool_mgr)
كما يوضّح المثال أعلاه، يمكن لعدة عملاء مشاركة مدير مجمّع واحد، أو يمكن إنشاء مدير مجمّع منفصل لكل عميل. لمزيد من التفاصيل حول الخيارات المتاحة عند إنشاء PoolManager، راجع وثائق urllib3.
آخر تعديل في ٢٥ يونيو ٢٠٢٦