You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Turso异步事务中console.log无输出及插入ID获取失败问题

单事务下Turso边缘数据库批量插入后获取ID异常问题

需求与问题

核心需求

  • 向数据库插入数据并获取对应自增ID;
  • 插入关联数据组并批量获取各自ID;
  • 将前两步的ID插入关联映射表。

异常表现

该流程在SQLite单事务中可正常运行,但切换到Turso边缘数据库后出现以下问题:

  • 使用forEach循环处理关联数据时,函数内console.log(insertedProponentIds)输出空数组,但接口最终能返回有效ID数组;
  • 改用for of循环后,触发「Invalid insertedProponentId data」错误,无法正确获取插入ID,导致关联映射表插入操作无法执行。

原始代码

function buildRouter(env: Env): RouterType {
    const router = Router();

    router.post("/api/main-form", async (request) => {
        const db = buildDB(env)
        const formData = await request.json();

        const loadedFormInfo: any = await db.transaction(async (tx) => {
            // 插入主表并获取ID
            const insertedFormId: any = tx.insert(formDataTable)
                .values({
                    dateOption: formData.dateOption,
                    timeZone: formData.timeZone,
                    utcTime: new Date(formData.utcTime),
                    localTime: formData.localTime,
                    title: formData.title,
                    tag: formData.tag,
                    latitude: formData.latitude,
                    longitude: formData.longitude,
                    createdAt: new Date()
                })
                .returning({formId: formDataTable.id});

            let formId = await insertedFormId.values();
            formId = formId[0].id

            // 插入关联数据并收集ID
            const proponentsData: Proponent[] = formData.proponents;
            let insertedProponentIds: Number[] = [];
            proponentsData.forEach(async proponent => {
                let insertedProponentId = tx.insert(proponentsTable)
                    .values({
                        formId: formId,
                        team: proponent.team,
                        name: proponent.name,
                        email: proponent.email,
                        createdAt: new Date()
                    }).returning({proponentId: proponentsTable.id});

                let proponentId = await insertedProponentId.values();
                proponentId = proponentId[0].id;
                insertedProponentIds.push(proponentId);
            });

            console.log(insertedProponentIds)  // 输出空数组
            return insertedProponentIds // 接口返回有效数组

// 第三步插入关联映射表的代码位置 //

        });

        console.log('outside: ', loadedFormInfo)
        const responseBody = JSON.stringify( {'return_val': loadedFormInfo} );
        const response = new Response(responseBody, { status: 200, headers: { 'Content-Type': 'application/json' } });

        return response;
    });

    router.all("*", () => new Response("Not Found.", { status: 404 }));

    return router;
};

尝试修改后的代码

// 插入关联数据并收集ID
const proponentsData: Proponent[] = formData.proponents;
let insertedProponentIds: Number[] = [];
for (const proponent of proponentsData) {
    try {
        const insertedProponentId = await tx.insert(proponentsTable)
            .values({
                formId: formId,
                team: proponent.team,
                name: proponent.name,
                email: proponent.email,
                createdAt: new Date()
            })
            .returning({ proponentId: proponentsTable.id });

        if (insertedProponentId && insertedProponentId[0] && insertedProponentId[0].id) {
            const proponentId = insertedProponentId[0].id;
            insertedProponentIds.push(proponentId);
        } else {
            console.error("Invalid insertedProponentId data:", insertedProponentId);
        }
    } catch (error) {
        console.error("Error inserting proponent:", error);
    }
}

console.log(insertedProponentIds)
return insertedProponentIds

报错信息

[mf:inf] POST /api/main-form 500 Internal Server Error (757ms)
⎔ Reloading local server...
[mf:inf] Updated and ready on http://127.0.0.1:8787/
Invalid insertedProponentId data: SQLiteInsert {
  session: _LibSQLSession,
  dialect: SQLiteAsyncDialect,
  config: Object,
  run: ,
  all:
  ...
}
Invalid insertedProponentId data: SQLiteInsert {
  session: _LibSQLSession,
  dialect: SQLiteAsyncDialect,
  config: Object,
  run: ,
  all:
  ...
}
Array(0) [  ]
outside:  Array(0) [  ]
[mf:inf] POST /api/main-form 200 OK (49ms)

问题根源与解决方案

问题根源

  1. forEach异步执行问题:forEach不会等待内部async函数执行完成,console.log执行时数组还未被填充,但事务最终会等待所有异步操作结束,因此接口能返回正确结果;
  2. 遗漏.values()调用:Turso插入操作返回的是SQLiteInsert对象,必须调用.values()才能获取实际返回数据,之前直接判断对象结构的逻辑错误;
  3. 字段名匹配错误:.returning({proponentId: proponentsTable.id})定义的返回字段是proponentId,而非id,之前的代码错误访问了id字段。

修正后的代码

// 插入关联数据并收集ID
const proponentsData: Proponent[] = formData.proponents;
let insertedProponentIds: Number[] = [];
for (const proponent of proponentsData) {
    try {
        // 关键:调用.values()获取插入后的返回数据
        const insertedProponentResult = await tx.insert(proponentsTable)
            .values({
                formId: formId,
                team: proponent.team,
                name: proponent.name,
                email: proponent.email,
                createdAt: new Date()
            })
            .returning({ proponentId: proponentsTable.id })
            .values();

        // 匹配.returning定义的字段名proponentId
        if (insertedProponentResult?.[0]?.proponentId) {
            insertedProponentIds.push(insertedProponentResult[0].proponentId);
        } else {
            console.error("Invalid insertedProponentId data:", insertedProponentResult);
        }
    } catch (error) {
        console.error("Error inserting proponent:", error);
    }
}

console.log(insertedProponentIds)
// 此处可执行关联映射表插入操作,示例:
// await tx.insert(关联映射表).values(
//   insertedProponentIds.map(id => ({ formId, proponentId: id }))
// );
return insertedProponentIds

内容的提问来源于stack exchange,提问作者avnav99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 06:16:02