Tableau Hyper API - سيشكرك فريق BI

نريد أن نخبرك كيف ساعدنا فريق ذكاء الأعمال لدينا على تنظيم العملية التلقائية لتسليم البيانات إلى خادم Tableau من MongoDB باستخدام تنسيق تخزين بيانات التابلويد "hyper" ، ويتم تنفيذ عملية إعداد إنشاء البيانات من خلال واجهة ويب بسيطة.



في البداية ، سوف نصف بإيجاز كيف بدت العملية قبل وبعد تعليمنا منتجنا الداخلي A1 لجمع مصادر البيانات برمجيًا ونشرها على خادم Tableau. ثم سنلقي نظرة فاحصة على مشكلة الأمر BI والحل الذي تم العثور عليه ، ونلقي نظرة أيضًا تحت الغطاء (هنا حول إنشاء ملف. hyper ، ونشر ملف على خادم tableau وتحديث هايبر). مرحبا بكم تحت الخفض!



Tableau Hyper API - سيشكرك فريق BI




نحن في مجموعة DAN الإعلانية نعمل كثيرًا مع بيانات مراقبة الإعلانات من Mediascope ، وهو مقياس صناعي في سوق الوسائط. هناك سيناريوهات مختلفة: يقوم بعض الموظفين بتحميل البيانات الأولية ، والبعض الآخر يستخدم قواعد البيانات الجاهزة ، ويطلب شخص ما تطوير لوحات المعلومات الآلية بناءً على هذه البيانات. دعنا نتحدث عن السيناريو الأخير بمزيد من التفصيل - يقوم مطورو ذكاء الأعمال لدينا بتجميع لوحات المعلومات في Tableau ، ولكن قبل البدء في "الرسم" ، يحتاجون أيضًا إلى نقل البيانات إلى التنسيق المطلوب المناسب للتطوير.



يمكن تقسيم مسار حياة البيانات من المواد الخام إلى الرسوم البيانية الآلية الجميلة تقريبًا إلى 4 خطوات:



  1. الحصول على البيانات الأولية
  2. تنظيف البيانات ومراجعتها
  3. تكوين مصادر البيانات لل Tableau
  4. تطوير التصورات


كانت



قبل أن نتعلم كيفية إنشاء مصادر البيانات برمجيًا لـ Tableau ، بدت العملية كما يلي:



عملية الحياة القديمة


1. الحصول على البيانات الأولية يقوم



المستخدمون بإنشاء تقارير مجدولة من خلال الأداة الداخلية A1. سنتحدث عنها بمزيد من التفصيل أدناه.



2. تنظيف البيانات وتعديلها



يتم تضمين إمكانية تحويل البيانات أيضًا في أداة A1 ، وبعد ذلك يمكن تحميل البيانات التي تم تنظيفها إلى xslx / csv والاستمرار في العمل معهم خارج الأداة. وتجدر الإشارة هنا إلى أن بعض المستخدمين يقصرون أنفسهم على النقطة الأولى وبعد تحميل التقارير ، يقومون بتعديل البيانات بأنفسهم.



3. تكوين مصادر البيانات للجدول



في السابق ، كان عملاء لوحة المعلومات يأتون بمجموعة من Excels قاموا بإنشائها في الفقرات السابقة. وجلب مطورو ذكاء الأعمال هذه الأعمال السابقة إلى مصدر بيانات واحد (عامية تابلويد) بمفردهم. لم يكن من الممكن دائمًا قصر أنفسنا على أدوات Tableau ؛ غالبًا ما كتبوا نصوصًا بلغة Python.



4. تطوير التصورات



أخيرًا ، يتمثل رأس جبل الجليد في إنشاء لوحة معلومات ونشرها على خادم Tableau ، حيث يمكن للعميل رؤيتها. من الناحية العملية ، غالبًا ما يستغرق العرض وقتًا أقل من جمع البيانات وإعداد التحديثات.



تراكم الألم في الخطوة الثالثة ، مع نمو عدد الحلول المخصصة ، والتي كانت صيانتها وتنفيذها باهظة الثمن. أيضًا ، كانت الأخطاء في البيانات من الخطوة الثانية تتسرب بانتظام - كان برنامج Excel الوسيط بين النظامين (A1 و Tableau) يدفع المستخدم: "لنصحح شيئًا ما باستخدام الأقلام ، لن يلاحظ أحد".



أصبح



كانت المهمة الرئيسية هي القضاء على الفراء السابق بين خطوتين و 3 خطوات. نتيجة لذلك ، قمنا بتعليم A1 جمع مصادر البيانات ونشرها على خادم Tableau. إليكم ما حدث:



عملية حياة جديدة


الآن تحدث الخطوات من 1 إلى 3 في A1 ، عند الإخراج ، يتلقى فريق BI مصدر بيانات منشور على Tableau Server لتطوير المرئيات. أصبح Hyper API رابط الاتصال ، والذي سيتم مناقشته بشكل أكبر.



النتائج



تم تقليل عدد العقد عند العمل في أدوات مختلفة. الآن أصبح من الصعب ارتكاب خطأ في مكان ما أثناء العملية ، ومن الأسهل تحديد مكان حدوث الخطأ ، يستغرق التحقيق في حالات الفشل وقتًا أقل. يحذر النظام المستخدمين من الأخطاء الشائعة.



وفر وقتًا لفريق BI . في السابق ، كان هناك القليل من حلول النماذج والكثير من التخصيصات. في أغلب الأحيان ، تمت إضافة معالجة Python لكل مشروع. في حالات نادرة ، حيث لم تكن هناك حاجة للمعالجة ، عملنا مباشرة في Tableau Desktop (أداة التطوير الرئيسية).



الآن يتم إعداد مصدر البيانات: انقر فوق الحقول المطلوبة في واجهة A1 ، وحدد أي منها نقوم بتوسيعه إلى سطور (إذا لزم الأمر) وحدد نوع الحقول مسبقًا بشكل اختياري.



لا نقوم بتحميل خادم Tableauتحديث مصادر البيانات الضخمة - يتم التحديث بواسطة A1 ، ويتم تنزيل ملف هايبر جاهز على الخادم.



* مكافأة - نشجع المستخدمين على العمل داخل A1. إذا قام بعض المستخدمين سابقًا ، بعد تفريغ التقارير الأولية ، بتعديلها يدويًا خارج الأداة ، الآن ، نظرًا لأن العملية برمتها من الخطوات 1 إلى 3 تحدث في A1 ، فمن الأسهل على المستخدمين إعداد عملية التنظيف هناك.



المشكلة والحل



قليلا عن A1



قبل أن نبدأ في الحديث عن الحل الذي نقدمه ، نحتاج إلى التحدث عن منتجنا الداخلي A1 ، والذي قمنا بإرفاق جيل مصادر البيانات به.



A1 هو منتج داخلي للشركة ، وهو مصمم لتبسيط سير العمل للموظفين الذين تكون وظيفتهم الرئيسية على النحو التالي:



  • استرداد البيانات من منتجات برامج MediaScope
  • قم بإحضار (تنظيف) هذه البيانات في نموذج مناسب لمحللي الموضوع
  • إذا لزم الأمر ، قم بإعداد البيانات لإنشاء لوحات المعلومات (سنتحدث عن هذا اليوم)


بعد انتهاء المستخدم من تنظيف البيانات ، يتم تخزينها في نظام A1. في مصطلحاتنا ، هذا يسمى "الحاوية". الحاوية هي وثيقة عادية في MongoDB ، والتي نحتاج إلى نقلها إلى خادم Tableau.



مشكلة فريق BI



احتاج فريق تطوير ذكاء الأعمال لدينا إلى الحصول على البيانات بطريقة ما من A1 ، التي تم تخزينها في MongoDB ، وبناء لوحات معلومات بناءً على البيانات المستلمة. بادئ ذي بدء ، حاولنا جلب البيانات من MongoDB باستخدام أدوات لوحة النتائج العادية ، لكن هذا لم يحل المشكلة:



  • نظرًا لأنه يتم تخزين البيانات في MongoDB ، يتم تلقي البيانات ذات الهيكل التعسفي عند مدخل لوحة النتائج ، مما يعني أنه سيتعين عليك الحفاظ على هذا المنطق باستمرار.
  • لتجميع البيانات من MongoDB ، كان من الضروري سحب سجلات معينة من المجموعة ، وليس المجموعة بأكملها - لا يمكن لبرنامج تشغيل Tableau القيام بذلك.
  • من بين أمور أخرى ، لم يكن الحصول على البيانات كافيًا: في بعض الأحيان كان يجب "توسيع" - "إلغاء تنشيط" بعض الأعمدة إلى صفوف. وهو الأمر أيضًا لم يكن من السهل القيام به ، من الكلمة على الإطلاق.


ما الذي توصلنا إليه



تقرر محاولة حل هذه المشكلة بدراجتي باستخدام مكتبة Tableau Hyper API . تتيح لك هذه المكتبة إنشاء ملف بتنسيق .hyper ، حيث يسهل إضافة البيانات إليه ، ثم استخدامه كمصدر بيانات لإنشاء لوحة معلومات على لوحة الخادم.



كما يصف مطورو لوحة النتائج الهايبر بأنفسهم:

Hyper هو محرك بيانات عالي الأداء في الذاكرة يساعد العملاء على تحليل مجموعات البيانات الكبيرة أو المعقدة بسرعة من خلال تقييم استعلامات قاعدة البيانات بكفاءة. استنادًا إلى منصة Tableau ، يستخدم Hyper تقنيات إنشاء التعليمات البرمجية الديناميكية الخاصة وتقنيات التزامن المتقدمة لتحقيق أداء عالٍ في المقتطفات والاستفسارات.
تكون عملية العمل التقريبية في برنامجنا كما يلي:



  • يختار المستخدم الحاويات والأعمدة المطلوبة
  • يقوم النظام بسحب البيانات من الحاويات
  • بناءً على البيانات الواردة ، يحدد النظام أنواع الأعمدة
  • يتم تهيئة إنشاء Hyper وإدخال البيانات فيه
  • يتم تحميل الهايبر على خادم لوحة النتائج
  • يرى مطورو BI الهايبر على الخادم ويقومون بإنشاء لوحة معلومات تستند إليها


عند سكب بيانات جديدة في الحاويات ، سيتم إعطاء النظام إشارة تفيد بضرورة تحديث الهايبر:



  • سيقوم النظام بتنزيل الهايبر من خادم لوحة النتائج
  • سيتم أخذ بيانات جديدة من MongoDB وتحديث ملف Hyper
  • بعد ذلك ، يقوم النظام بتحميل هايبر جديد إلى الخادم ، والكتابة فوق الخادم الحالي.
  • يحتاج المستخدم فقط إلى النقر فوق الزر "تحديث" لعرض أحدث المعلومات في لوحة التحكم


ما يراه المستخدم



كما ذكرنا سابقًا ، A1 هو تطبيق ويب. استخدمنا Vue.js و Vuetify لإنشاء خدمة إنشاء فائقة السرعة أمامية.



واجهة التطبيق مقسمة إلى ثلاث شاشات.



شاشة اختيار الحاوية



في الشاشة الأولى ، يختار المستخدم الحاويات والأعمدة المطلوبة.



إذا تم تمكين الخيار "Unpivot" ، فسيتم إنشاء عمودين إضافيين في hyper: المتغير - أسماء الأعمدة التي تم تحديدها بواسطة عمود المقاييس والقيم - القيم من هذه الأعمدة.



يضيف عمود البعد عمودًا بالعمود المحدد بنفس الاسم إلى hyper. عدد الأعمدة المختارة الأبعاد وأسمائها يجب أن تكون هي نفسها في جميع الحاويات حتى لا يتم انتهاك سلامة الجدول في hyper ، لذلك يوجد عمود "Hyper name" ، والذي يسمح لك بتحديد اسم العمود المحدد ، إذا تم تسميتها بشكل مختلف في الحاويات.



سجلات عملية الخلق المفرط



هذا ينهي عملية إعداد الهايبر. يحتاج المستخدم فقط إلى الانتقال إلى الشاشة الثانية ، والنقر فوق "إنشاء هايبر" ومشاهدة تقدم الأحداث في السجلات.



إعدادات إضافية



تحتوي الشاشة الثالثة على إعدادات إضافية:



  • يمكنك تشغيل تجاهل التحديثات إذا لم نكن بحاجة للنظام لتحديث الهايبر تلقائيًا
  • يمكنك تحديد بريد إلكتروني لإرسال تقارير التحديث
  • يمكنك تحديد نوع البيانات يدويًا لعمود القيم (يُستخدم فقط في وضع unpivot): تعويم ، أو سلسلة ، أو يحدده النظام تلقائيًا (سنتحدث عن الأنواع أكثر)
  • يمكنك أيضًا تحديد أنواع البيانات للأعمدة المحددة في الحاويات.


ماذا يوجد تحت الغطاء



A1 مكتوب بلغة بايثون. للعمل مع البيانات ، نستخدم Pandas ، ونقوم بترتيب البيانات من حيوانات الباندا لتقطيعها وتخزينها في MongoDB GridFS.



عندما يتم تلقي أمر إنشاء فرط ، يقوم النظام بتنفيذ العمليات التالية:



  • يقوم بتفريغ جميع الحاويات الضرورية من MongoDB وإلغاء تسلسل البيانات في بيانات الباندا
  • تحضير البيانات: يترك فقط الأعمدة المطلوبة في إطارات البيانات ، ويمنحها أسماء جديدة ، ويوسع الجداول إذا لزم الأمر عبر pandas.melt
  • إذا قام المستخدم بتعيين نوع البيانات للأعمدة ، فقم بتحويل البيانات إما إلى float32 أو إلى سلسلة
  • بعد كل الأعمال التحضيرية مع البيانات ، يقوم النظام بإنشاء ملف عبر hyper api ويرسل الملف إلى خادم لوحة النتائج عبر tabcmd.


يجدر الحديث قليلاً عن أنواع بيانات الأعمدة. تتمثل إحدى ميزات تخزين البيانات في حاويات A1 ​​في أن المستخدمين لا يهتمون بالأنواع التي يجب تعيينها للأعمدة ، بل تقوم الباندا بذلك من أجلهم بشكل مثالي: يتكيف النظام بهدوء مع المواقف التي تكون فيها الأرقام وقيم السلسلة موجودة في عمود. ومع ذلك ، فإن الهايبر لا يحب هذا: إذا أخبرته أن العمود يجب أن يكون من النوع int ، فسيقسم النظام عند محاولة إدخال أي شيء آخر غير العدد الصحيح. لذلك ، تقرر استخدام نوعين فقط من البيانات في الفائق: سلسلة وعائمة.



لذلك ، توصلنا إلى المبدأ العام للعمل ، لنتحدث عن العمل مع hyper نفسها.



إنشاء ملف هايبر



للعمل مع Hyper API ، تحتاج إلى تثبيت المكتبة ، يمكنك تنزيلها من الموقع الرسمي هنا . هناك أيضًا بعض الأمثلة الجيدة عن كيفية العمل باستخدام هذه الأداة. سوف نشير بإيجاز إلى النقاط الرئيسية.



ملف hyiper نفسه هو نوع من قواعد البيانات ، يذكرنا إلى حد ما بـ SQLite. من خلال api ، يمكنك الوصول إلى البيانات باستخدام بناء جملة SQL:



f"SELECT {escape_name('Customer ID')} FROM {escape_name('Customer')}"


نظرًا لأن نظامنا مكتوب بلغة Python ، فسوف نستخدم المكتبة أيضًا للغة المقابلة. عند إنشاء ملف ، يجب علينا تحديد اسم المخطط واسم الجدول والأعمدة بأنواعها. يجب تسمية اسم المخطط والجدول "استخراج" ، لأنه في هذا المخطط مع الجدول الذي يتسلق خادم Tableau لاستخراج البيانات للكتب.



with HyperProcess(Telemetry.SEND_USAGE_DATA_TO_TABLEAU) as hyper:
    with Connection(
        hyper.endpoint, self.fullpath_hyper, CreateMode.CREATE_AND_REPLACE
    ) as connection:
        connection.catalog.create_schema("Extract")
        main_table = TableName("Extract", "Extract")
        example_table = TableDefinition(main_table)


بعد إنشاء الجدول ، نحتاج إلى إنشاء أعمدة وتعيين الأنواع. كما قلنا سابقًا ، تحتوي بياناتنا على نوعين فقط (عائم أو سلسلة) ، لذلك بناءً على نوع الأعمدة في إطار البيانات ، قمنا بتعيين هذا للأعمدة:



for column in dataframe.columns:
    if dataframe[column].dtype.name in ("category", "object"):
        example_table.add_column(TableDefinition.Column(column, SqlType.text()))

    elif dataframe[column].dtype.name in ("float32"):
        example_table.add_column(
            TableDefinition.Column(column, SqlType.double())
        )

    connection.catalog.create_table(example_table)


بعد إنشاء الجدول ، يمكنك إدراج البيانات:



with Inserter(connection, example_table) as inserter:
    for val in dataframe.values:
        inserter.add_row(val.tolist())
    inserter.execute()


نحن هنا نمرر عبر إطار البيانات سطرًا بسطر ونجمع القائمة بالقيم عبر inserter.add_row () . في الواقع ، هناك دالة add_rows () في هايبر api ، والتي تأخذ قائمة من القوائم وتدرج القيم بالفعل. لماذا لم يتم ذلك؟ لحفظ ذاكرة الوصول العشوائي (RAM): لتقديم قائمة بقوائم القيم من إطار بيانات ، عليك أن تطلب من الباندا القيام بالقيم .olist () . وعندما يكون لديك 150 مليون سطر من البيانات ، يتبين أنها عملية مكلفة للغاية بالنسبة لذاكرة الوصول العشوائي ، في حين أن هذا لا يؤثر على الأداء بأي شكل من الأشكال (على أي حال ، لم يُلاحظ أنه بسبب التكرار التكراري عبر الخطوط ، فإن سرعة إنشاء فرط غرق بطريقة ما). بالإضافة إلى add_rows ()يعمل مثل السكر النحوي: فهو يأخذ في الواقع قائمة من القوائم ويضيف البيانات بشكل متكرر.



هذا يخلص إلى إنشاء hyper. بعد ذلك ، نحتاج إلى نشره على الخادم.



نشر ملف على خادم لوحة



للوصول إلى خادم tableau ، سنستخدم الأداة المساعدة tabcmd - وهي أداة مساعدة لوحدة التحكم تتيح لك الاتصال بالخادم وأداء الوظائف الإدارية - إنشاء مستخدمين ومجموعات وكتب وغير ذلك.



سنقوم بتشغيل الأمر tabcmd خلال عملية بايثون الفرعية.



popen = subprocess.Popen(
    f'/opt/tableau/tabcmd/bin/tabcmd publish "{fullpath_hyper}" -n "{filename}" -o -r "A1_test" '
    '-s http://tableau.domain.com -u "username" -p "password" --no-certcheck',
    shell=True,
    stderr=subprocess.PIPE,
    stdout=subprocess.PIPE,
)
return_code = popen.wait()
if return_code:
    error = str(popen.communicate()[1])
    return f"     . {error}"


نقوم بتمرير الأمر والمفاتيح التالية إلى tabcmd:



  • النشر : تحميل ملف على الخادم
  • -n (--name) : ما اسم الملف الذي سيكون على الخادم
  • -o (--overwrite) : إذا كان هناك ملف بهذا الاسم ، فاكتب
  • -r “A1_test” (--project): ( )
  • -s (--server): tableau-
  • -u -p:
  • --no-certcheck: SSL-




لقد توصلنا إلى كيفية إنشاء هايبر جديد ، ولكن ماذا نفعل عندما يتكون الهايبر من عشر حاويات ويتلقى أحدهم بيانات جديدة؟ سنقوم بتحديث هايبر.



عند وصول بيانات جديدة إلى الحاوية ، يبحث النظام لمعرفة ما إذا كان هناك أي فائق يستخدم هذه الحاوية. إذا كان هناك ، فإن المهمة هي تحديث hyper.



لفهم البيانات الموجودة في أي حاوية في hyper ، يقوم النظام أيضًا بإنشاء عمود container_id إضافي عند إنشاء hyper. مع هذا النهج ، يصبح التحديث بسيطًا جدًا:



  • نأخذ الملف من الخادم
  • نحذف جميع الأسطر في hyper ، حيث تساوي container_id الحاوية المحدثة
  • أدخل أسطرًا جديدة
  • قم بتحميل ملف الكتابة الفوقية مرة أخرى إلى الخادم.


تختلف عملية استرداد الملف قليلاً عن عملية تنزيله. بادئ ذي بدء ، لن نأخذ ملف .hyper من الخادم ، ولكن أرشيف tdsx ، الذي سنقوم بعد ذلك بفك ضغطه وفتحه.



من أجل التقاط الملف ، نستخدم tabcmd:



popen = subprocess.Popen(
    f'/opt/tableau/tabcmd/bin/tabcmd get "datasources/{filename_tdsx}" '
    f'-s http://tableau.domain.com -u "username" -p "password" '
    f'--no-certcheck -f "{fullpath_tdsx}"',
    shell=True,
    stderr=subprocess.PIPE,
    stdout=subprocess.PIPE,
)
return_code = popen.wait()
if return_code:
    error = str(popen.communicate()[1])
    return f". {error}"


هنا نستخدم الأوامر والمفاتيح التالية:



  • get : الحصول على ملف من الخادم. إذا كان ملف test.hyper موجودًا على الخادم ، فأنت بحاجة إلى الرجوع إلى ملف test.tdsx ، وكلها موجودة في دليل مصدر البيانات (لم أتمكن من البحث عن سبب وجود مثل هذه الميزة للعمل في لوحة النتائج ، إذا كنت تعلم ، شارك في التعليقات)
  • -f (--filename) : المسار الكامل ، بما في ذلك اسم الملف والامتداد ، حيث يتم حفظ الملف


بعد تنزيل الملف ، يجب فك ضغطه عبر ملف مضغوط:



with zipfile.ZipFile(fullpath_tdsx, "r") as zip_ref:
    zip_ref.extractall(path)


بعد فك الضغط ، سيكون الهايبر في دليل ./Data/Extracts .



الآن بعد أن أصبح لدينا الإصدار الحالي من الملف ، يمكننا إزالة الأسطر غير الضرورية منه:



table_name = TableName("Extract", "Extract")

with HyperProcess(Telemetry.SEND_USAGE_DATA_TO_TABLEAU) as hyper:
    with Connection(hyper.endpoint, self.fullpath_hyper) as connection:
        connection.execute_query(
            f"DELETE FROM {table_name} WHERE "
            f'{escape_name("container_id")}={container_id}'
        ).close()


حسنًا ، لقد تم بالفعل وصف إدراج ملف ونشره أعلاه.



خاتمة



ما هو بيت القصيد؟ بعد الانتهاء من العمل على تنفيذ إنشاء الملفات الفائقة وتسليمها التلقائي إلى خادم tableau ، قللنا بشكل كبير الحمل على فريق BI ، وأصبح تحديث البيانات في لوحة القيادة أسهل ، والأهم من ذلك ، أسرع. لم يكن التعارف مع hyper api مؤلمًا ، والوثائق مكتوبة جيدًا ، وكان دمج التكنولوجيا في نظامنا أمرًا سهلاً.



نشكرك على اهتمامك! إذا كان لديك أي أسئلة أو تعليقات ، يرجى تركها في التعليقات.



تمت كتابة المقال بالاشتراك مع فاسيلي لافروف (VasilyFromOpenSpace) — -



All Articles