روابط إدخال جداول Azure لوظائف Azure

استخدم ربط إدخال جداول Azure لقراءة جدول في Azure Cosmos DB للجدول أو Azure Table Storage.

للحصول على معلومات حول تفاصيل الإعداد والتكوين، راجع الاستعراض العام.

هام

تستخدم هذه المقالة علامات التبويب لدعم إصدارات متعددة من نموذج البرمجة Node.js. يتوفر نموذج v4 بشكل عام وتم تصميمه للحصول على تجربة أكثر مرونة وبديهية لمطوري JavaScript وTypeScript. لمزيد من التفاصيل حول كيفية عمل نموذج v4، راجع دليل مطور Azure Functions Node.js. لمعرفة المزيد حول الاختلافات بين v3 وv4، راجع دليل الترحيل.

مثال

يعتمد استخدام الربط على إصدار حزمة الامتداد وصيغة C# المستخدمة في تطبيق الوظيفة الخاص بك، والتي يمكن أن تكون واحدة مما يلي:

تعمل مكتبة فئة معالجة عامل معزولة تعمل دالة C# المحولة برمجيا في عملية معزولة عن وقت التشغيل.

اختر إصدارًا لعرض أمثلة على الوضع والإصدار.

تمثل الفئة التالية MyTableData صفاً من بيانات في الجدول:

public class MyTableData : Azure.Data.Tables.ITableEntity
{
    public string Text { get; set; }

    public string PartitionKey { get; set; }
    public string RowKey { get; set; }
    public DateTimeOffset? Timestamp { get; set; }
    public ETag ETag { get; set; }
}

تقرأ الدالة التالية، التي يتم تشغيلها بواسطة مشغل Queue Storage، مفتاح صف من قائمة الانتظار، والذي يتم استخدامه للحصول على الصف من جدول الإدخال. يربط التعبير {queueTrigger} الصف مفتاح الصف ببيانات تعريف الرسالة، وهي سلسلة الرسالة.

[Function("TableFunction")]
[TableOutput("OutputTable", Connection = "AzureWebJobsStorage")]
public static MyTableData Run(
    [QueueTrigger("table-items")] string input,
    [TableInput("MyTable", "<PartitionKey>", "{queueTrigger}")] MyTableData tableInput,
    FunctionContext context)
{
    var logger = context.GetLogger("TableFunction");

    logger.LogInformation($"PK={tableInput.PartitionKey}, RK={tableInput.RowKey}, Text={tableInput.Text}");

    return new MyTableData()
    {
        PartitionKey = "queue",
        RowKey = Guid.NewGuid().ToString(),
        Text = $"Output record with rowkey {input} created at {DateTime.Now}"
    };
}

ترجع الدالة التالية المشغلة بواسطة قائمة الانتظار أول 5 كيانات كـ IEnumerable<T>، مع تعيين قيمة مفتاح القسم كرسالة قائمة الانتظار.

[Function("TestFunction")]
public static void Run([QueueTrigger("myqueue", Connection = "AzureWebJobsStorage")] string partition,
    [TableInput("inTable", "{queueTrigger}", Take = 5, Filter = "Text eq 'test'", 
    Connection = "AzureWebJobsStorage")] IEnumerable<MyTableData> tableInputs,
    FunctionContext context)
{
    var logger = context.GetLogger("TestFunction");
    logger.LogInformation(partition);
    foreach (MyTableData tableInput in tableInputs)
    {
        logger.LogInformation($"PK={tableInput.PartitionKey}, RK={tableInput.RowKey}, Text={tableInput.Text}");
    }
}

يتم استخدام الخاصيتين Filter وTake للحد من عدد الكيانات التي تم إرجاعها.

يظهر المثال التالي دالة HTTP المشغلة المسؤولة عن إرجاع قائمة بكائنات الشخص الموجود في قسم محدد داخل تخزين جدول. في المثال، يُستخرج مفتاح القسم من مسار http؛ بينما يُستخرج tableName والاتصال من إعدادات الدالة.

public class Person {
    private String PartitionKey;
    private String RowKey;
    private String Name;

    public String getPartitionKey() { return this.PartitionKey; }
    public void setPartitionKey(String key) { this.PartitionKey = key; }
    public String getRowKey() { return this.RowKey; }
    public void setRowKey(String key) { this.RowKey = key; }
    public String getName() { return this.Name; }
    public void setName(String name) { this.Name = name; }
}

@FunctionName("getPersonsByPartitionKey")
public Person[] get(
        @HttpTrigger(name = "getPersons", methods = {HttpMethod.GET}, authLevel = AuthorizationLevel.FUNCTION, route="persons/{partitionKey}") HttpRequestMessage<Optional<String>> request,
        @BindingName("partitionKey") String partitionKey,
        @TableInput(name="persons", partitionKey="{partitionKey}", tableName="%MyTableName%", connection="MyConnectionString") Person[] persons,
        final ExecutionContext context) {

    context.getLogger().info("Got query for person related to persons with partition key: " + partitionKey);

    return persons;
}

يمكن أيضًا للتعليق التوضيحي TableInput أن يستخرج الروابط من نص json الخاص بالطلب، كما في المثال التالي.

@FunctionName("GetPersonsByKeysFromRequest")
public HttpResponseMessage get(
        @HttpTrigger(name = "getPerson", methods = {HttpMethod.GET}, authLevel = AuthorizationLevel.FUNCTION, route="query") HttpRequestMessage<Optional<String>> request,
        @TableInput(name="persons", partitionKey="{partitionKey}", rowKey = "{rowKey}", tableName="%MyTableName%", connection="MyConnectionString") Person person,
        final ExecutionContext context) {

    if (person == null) {
        return request.createResponseBuilder(HttpStatus.NOT_FOUND)
                    .body("Person not found.")
                    .build();
    }

    return request.createResponseBuilder(HttpStatus.OK)
                    .header("Content-Type", "application/json")
                    .body(person)
                    .build();
}

يستخدم المثال التالي عامل تصفية للاستعلام عن الأشخاص الذين يحملون اسمًا معينًا في جدول Azure، وللحد من عدد المطابقات المحتملة لتصل إلى 10 نتائج.

@FunctionName("getPersonsByName")
public Person[] get(
        @HttpTrigger(name = "getPersons", methods = {HttpMethod.GET}, authLevel = AuthorizationLevel.FUNCTION, route="filter/{name}") HttpRequestMessage<Optional<String>> request,
        @BindingName("name") String name,
        @TableInput(name="persons", filter="Name eq '{name}'", take = "10", tableName="%MyTableName%", connection="MyConnectionString") Person[] persons,
        final ExecutionContext context) {

    context.getLogger().info("Got query for person related to persons with name: " + name);

    return persons;
}

يوضح المثال التالي ربط إدخال جدول يستخدم مشغل قائمة انتظار لقراءة صف جدول واحد. يحدد الربط وpartitionKey.rowKey تشير rowKeyالقيمة "{queueTrigger}" إلى أن مفتاح السجل يأتي من سلسلة رسائل الصف.

import { app, input, InvocationContext } from '@azure/functions';

const tableInput = input.table({
    tableName: 'Person',
    partitionKey: 'Test',
    rowKey: '{queueTrigger}',
    connection: 'MyStorageConnectionAppSetting',
});

interface PersonEntity {
    PartitionKey: string;
    RowKey: string;
    Name: string;
}

export async function storageQueueTrigger1(queueItem: unknown, context: InvocationContext): Promise<void> {
    context.log('Node.js queue trigger function processed work item', queueItem);
    const person = <PersonEntity>context.extraInputs.get(tableInput);
    context.log('Person entity name: ' + person.Name);
}

app.storageQueue('storageQueueTrigger1', {
    queueName: 'myqueue-items',
    connection: 'MyStorageConnectionAppSetting',
    extraInputs: [tableInput],
    handler: storageQueueTrigger1,
});
const { app, input } = require('@azure/functions');

const tableInput = input.table({
    tableName: 'Person',
    partitionKey: 'Test',
    rowKey: '{queueTrigger}',
    connection: 'MyStorageConnectionAppSetting',
});

app.storageQueue('storageQueueTrigger1', {
    queueName: 'myqueue-items',
    connection: 'MyStorageConnectionAppSetting',
    extraInputs: [tableInput],
    handler: (queueItem, context) => {
        context.log('Node.js queue trigger function processed work item', queueItem);
        const person = context.extraInputs.get(tableInput);
        context.log('Person entity name: ' + person.Name);
    },
});

تستخدم الدالة التالية مشغل صف كي يقرأ سجل واحد في جدول باعتباره إدخال إلى دالة.

في هذا المثال، يحدد تكوين الربط قيمة صريحة للجدول partitionKey ويستخدم تعبيرًا للتمرير إلى rowKey. تشير كلمة rowKey تعبير{queueTrigger} إلى أن مفتاح السجل يأتي من سلسلة رسائل الصف.

تكوين الربط في function.json:

{
  "bindings": [
    {
      "queueName": "myqueue-items",
      "connection": "MyStorageConnectionAppSetting",
      "name": "MyQueueItem",
      "type": "queueTrigger",
      "direction": "in"
    },
    {
      "name": "PersonEntity",
      "type": "table",
      "tableName": "Person",
      "partitionKey": "Test",
      "rowKey": "{queueTrigger}",
      "connection": "MyStorageConnectionAppSetting",
      "direction": "in"
    }
  ],
  "disabled": false
}

تعليمة برمجية لـ PowerShell في run.ps1:

param($MyQueueItem, $PersonEntity, $TriggerMetadata)
Write-Host "PowerShell queue trigger function processed work item: $MyQueueItem"
Write-Host "Person entity name: $($PersonEntity.Name)"

تستخدم الدالة التالية HTTP كي يقرأ سجل واحد في جدول باعتباره إدخال إلى دالة.

في هذا المثال، يحدد تكوين الربط قيمة صريحة للجدول partitionKey ويستخدم تعبيرًا للتمرير إلى rowKey. يشير التعبير rowKey إلى {id} أن مفتاح الصف يأتي من جزء {id} المسار في الطلب.

تكوين الربط في ملف function.json:

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "messageJSON",
      "type": "table",
      "tableName": "messages",
      "partitionKey": "message",
      "rowKey": "{id}",
      "connection": "AzureWebJobsStorage",
      "direction": "in"
    },
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ],
      "route": "messages/{id}"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ],
  "disabled": false
}

رمز Python في ملف __init__.py :

import json

import azure.functions as func

def main(req: func.HttpRequest, messageJSON) -> func.HttpResponse:

    message = json.loads(messageJSON)
    return func.HttpResponse(f"Table row: {messageJSON}")

باستخدام هذا الربط البسيط، لا يمكنك التعامل برمجيًا مع حالة لم يتم فيها العثور على صف يحتوي على معرف مفتاح صف. لمزيد من تحديد البيانات الدقيقة، استخدم SDK التخزين.


السمات

تستخدم كل من مكتبات المعالجة والعامل المعزول C# السمات لتعريف الدالة. يستخدم البرنامج النصي C# بدلا من ذلك ملف تكوين function.json كما هو موضح في دليل البرمجة النصية C#‎.

في مكتبات فئة C #، يدعم ذلكTableInputAttribute الخصائص التالية:

خاصية السمة ‏‏الوصف
TableName اسم الجدول.
PartitionKey اختياري. مفتاح القسم الخاص بكيان الجدول المراد قراءته.
مفتاح الصف اختياري. مفتاح السجل الخاص بكيان الجدول المراد قراءته.
Take اختياري. الحد الأقصى لعدد الكيانات التي يجب قراءتها في IEnumerable<T>. لا يمكن استخدامها مع RowKey.
عامل التصفية اختياري. تعبير عامل تصفية OData للكيانات للقراءة في IEnumerable<T>. لا يمكن استخدامها مع RowKey.
Connection اسم إعداد التطبيق أو مجموعة الإعدادات التي تحدد كيفية الاتصال بخدمة الجدول. راجع الاتصالات.

تعليقات توضيحية

من مكتبة وقت تشغيل دوال Java، استخدم @TableInput التعليق التوضيحي على معلمات الدالة التي تأتي قيمتها من تخزين جدول. يمكن استخدام هذا التعليق التوضيحي مع أنواع Java الأصلية أو POJOs أو القيم االخالية Optional<T>. يدعم هذا التعليق التوضيحي العناصر التالية:

العنصر ‏‏الوصف‬
الاسم اسم المتغير الذي يمثل جدول أو كيان في تعليمة برمجية للدالة.
اسم الجدول اسم الجدول.
partitionKey اختياري. مفتاح القسم الخاص بكيان الجدول المراد قراءته.
rowKey اختياري. مفتاح السجل الخاص بكيان الجدول المراد قراءته.
الوقت المستغرق اختياري. الحد الأقصى لعدد الكيانات المراد قراءتها.
filter اختياري. تعبير عامل تصفية OData لإدخال الجدول.
الاتصال اسم إعداد التطبيق أو مجموعة الإعدادات التي تحدد كيفية الاتصال بخدمة الجدول. راجع الاتصالات.

التكوين

يوضح الجدول التالي الخصائص التي يمكنك تعيينها على الكائن الذي options تم تمريره input.table() إلى الأسلوب .

الخاصية ‏‏الوصف
اسم الجدول اسم الجدول.
partitionKey اختياري. مفتاح القسم الخاص بكيان الجدول المراد قراءته.
rowKey اختياري. مفتاح السجل الخاص بكيان الجدول المراد قراءته. لا يمكن استخدامها مع take أو filter.
الوقت المستغرق اختياري. الحد الأقصى لعدد الكيانات التي يجب إرجاعها. لا يمكن استخدامها مع rowKey.
filter اختياري. تعبير عامل تصفية OData للكيانات للعودة من الجدول. لا يمكن استخدامها مع rowKey.
الاتصال اسم إعداد التطبيق أو مجموعة الإعدادات التي تحدد كيفية الاتصال بخدمة الجدول. راجع الاتصالات.

التكوين

يشرح الجدول الآتي خصائص تكوين ربط البيانات التي عليك تعيينها في ملف function.json.

خاصية function.json ‏‏الوصف
النوع يجب تعيينه إلى table. تعيَّن هذه الخاصية تلقائيًا عند إنشاء الربط في مدخل Azure.
الاتجاه يجب تعيينه إلى in. تعيَّن هذه الخاصية تلقائيًا عند إنشاء الربط في مدخل Azure.
الاسم اسم المتغير الذي يمثل جدول أو كيان في تعليمة برمجية للدالة.
اسم الجدول اسم الجدول.
partitionKey اختياري. مفتاح القسم الخاص بكيان الجدول المراد قراءته.
rowKey اختياري. مفتاح السجل الخاص بكيان الجدول المراد قراءته. لا يمكن استخدامها مع take أو filter.
الوقت المستغرق اختياري. الحد الأقصى لعدد الكيانات التي يجب إرجاعها. لا يمكن استخدامها مع rowKey.
filter اختياري. تعبير عامل تصفية OData للكيانات للعودة من الجدول. لا يمكن استخدامها مع rowKey.
الاتصال اسم إعداد التطبيق أو مجموعة الإعدادات التي تحدد كيفية الاتصال بخدمة الجدول. راجع الاتصالات.

عندما تقوم بالتطوير محليًا، أضف إعدادات التطبيق في ملف local.settings.json في المجموعة Values.

الاتصالات

تمثل الخاصية connection مرجع لتكوين البيئة التي تحدد كيفية اتصال التطبيق بخدمة الجدول الخاص بك. ويجوز لها أن تحدد ما يلي:

إذا كانت القيمة المكونة مطابقة بدقة لإعداد واحد ومطابقة لبادئة للإعدادات الأخرى، يتم استخدام المطابقة الدقيقة.

سلسلة الاتصال

للحصول على سلسلة الاتصال للجداول في تخزين Azure Table، اتبع الخطوات الموضحة في إدارة مفاتيح الوصول إلى حساب التخزين. للحصول على سلسلة الاتصال للجداول في Azure Cosmos DB for Table، اتبع الخطوات الموضحة في الأسئلة المتداولة حول Azure Cosmos DB for Table.

يجب تخزين سلسلة الاتصال هذه في إعداد تطبيق باسم يطابق القيمة المحددة بواسطة خاصية connection لتكوين الربط.

إذا كان اسم إعداد التطبيق يبدأ بـ "AzureWebJobs"، يمكنك تحديد باقي الاسم هنا فقط. على سبيل المثال، إذا تم تعيين connection إلى "MyStorage"، وقت تشغيل الدوال يبحث عن إعداد تطبيق يُسمى "MyStorage". إذا تركت connection فارغة، سيستخدم وقت تشغيل الدوال سلسلة اتصال التخزين الافتراضية في إعدادات التطبيق التي تُسمى AzureWebJobsStorage.

الاتصالات القائمة على الهوية

إذا كنت تستخدم ملحق واجهة برمجة تطبيقات الجداول، فبدلا من استخدام سلسلة الاتصال مع سر، يمكنك أن يكون التطبيق يستخدم هوية Microsoft Entra. ينطبق هذا عند الوصول إلى الجداول في Azure Storage فحسب. لاستخدام هوية، يمكنك تعريف الإعدادات ضمن بادئة شائعة تعين إلى الخاصية connection في تكوين المشغل والربط.

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

الخاصية قالب متغير البيئة ‏‏الوصف مثال للقيمة
URI لخدمة الجدول <CONNECTION_NAME_PREFIX>__tableServiceUri1 عنوان URI لمستوى البيانات لخدمة جدول Azure Storage التي تتصل بها، باستخدام نظام HTTPS. https://<storage_account_name>.table.core.windows.net

يمكن استخدام 1<CONNECTION_NAME_PREFIX>__serviceUri كاسم مستعار. إذا تم توفير كلا النموذجين، tableServiceUri يتم استخدام النموذج. serviceUri لا يمكن استخدام النموذج عند استخدام تكوين الاتصال الكلي عبر الكائنات الثنائية كبيرة الحجم وقوائم الانتظار و/أو الجداول.

قد يتم تعيين خصائص أخرى لتخصيص الاتصال. راجع الخصائص الشائعة للاتصالات المعتمدة على الهوية.

serviceUri لا يمكن استخدام النموذج عند استخدام تكوين الاتصال الكلي عبر الكائنات الثنائية كبيرة الحجم وقوائم الانتظار و/أو الجداول في Azure Storage. يمكن ل URI تعيين خدمة الجدول فقط. كبديل، يمكنك توفير URI خصيصًا لكل خدمة تحت نفس البادئة، مما يسمح باستخدام اتصال واحد.

عند استضافتها في خدمة Azure Functions، تستخدم الاتصالات المستندة إلى الهوية هوية مدارة. تستخدم الهوية المعينة من قبل النظام بشكل افتراضي على الرغم من إمكانية تحديد هوية معينة من قبل المستخدم مع خصائص credential و clientID. لاحظ أن تكوين هوية معينة من المستخدم باستخدام معرف مورد غير معتمد. عند التشغيل في سياقات أخرى، مثل التنمية المحلية، يتم استخدام هوية المطور الخاصة بك بدلًا من ذلك، على الرغم من أنه يمكن تخصيصها. راجع التطوير المحلي من خلال الاتصالات القائمة على الهوية.

منح الإذن للهوية

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

هام

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

ستحتاج إلى إنشاء تعيين دور يوفر الوصول إلى خدمة جدول Azure Storage في وقت التشغيل. أدوار الإدارة مثل المالك ليست كافية. يعرض الجدول التالي الأدوار المضمنة الموصى بها عند استخدام ملحق Azure Tables مقابل Azure Storage في العملية العادية. قد يتطلب طلبك أذونات إضافية بناءً على الرمز الذي تكتبه.

نوع الربط مثال بشأن الأدوار المضمنة (Azure Storage1)
ربط بيانات الإدخال قارئ بيانات جدول التخزين
ربط بيانات الإخراج مساهم بيانات جدول التخزين

1 إذا كان تطبيقك يتصل بدلا من ذلك بالجداول في Azure Cosmos DB للجدول، فإن استخدام هوية غير مدعوم ويجب أن يستخدم الاتصال سلسلة الاتصال.

الاستخدام

يعتمد استخدام الربط على إصدار حزمة الامتداد وصيغة C# المستخدمة في تطبيق الوظائف الخاص بك، والتي يمكن أن تكون واحدة مما يلي:

تعمل مكتبة فئة معالجة عامل معزولة تعمل دالة C# المحولة برمجيا في عملية معزولة عن وقت التشغيل.

حدد إصدارًا للاطلاع على تفاصيل الاستخدام للوضع والإصدار.

عند العمل مع كيان جدول واحد، يمكن ربط إدخال جداول Azure بالأنواع التالية:

النوع ‏‏الوصف
نوع JSON القابل للتسلسل الذي ينفذ ITableEntity تحاول الدالات إلغاء تسلسل الكيان إلى نوع كائن CLR (POCO) قديم عادي. يجب أن ينفذ النوع ITableEntity أو أن يكون له خاصية سلسلة RowKey وخاصية سلسلة PartitionKey .
جدولEntity1 الكيان كنوع يشبه القاموس.

عند العمل مع كيانات متعددة من استعلام، يمكن ربط ربط إدخال جداول Azure بالأنواع التالية:

النوع ‏‏الوصف
IEnumerable<T> حيث T ينفذ ITableEntity تعداد للكيانات التي تم إرجاعها بواسطة الاستعلام. يمثل كل إدخال كيانا واحدا. يجب أن ينفذ النوع T ITableEntity أو أن يكون له خاصية سلسلة RowKey وخاصية سلسلةPartitionKey.
TableClient1 عميل متصل بالجدول. يوفر هذا أكبر قدر من التحكم لمعالجة الجدول ويمكن استخدامه للكتابة إليه إذا كان الاتصال لديه إذن كاف.

1 لاستخدام هذه الأنواع، تحتاج إلى الرجوع إلى Microsoft.Azure.Functions.Worker.Extensions.Tables 1.2.0 أو أحدث والتبعيات الشائعة لروابط نوع SDK.

تمنحك سمةTableInput حق الوصول إلى سجل جدول يشغّل دالة.

احصل على بيانات صف الإدخال باستخدام context.extraInputs.get().

يتم تمرير بيانات إلى معلمة إدخال على النحو المحدد بواسطة name المفتاح في الملف function.json. تحديد partitionKey و rowKey يسمح بتصفية إلى سجلات معينة.

يتم تمرير بيانات جدول إلى دالة على هيئة سلسلة JSON. إلغاء تسلسل رسالة عن طريق الاتصال json.loads كما هو موضح في مثالإدخال.

للحصول على تفاصيل استخدام محددة، راجع Example.

الخطوات التالية