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

如何在AdminBro/AdminJS中处理复合主键问题?

问题

我有三个数据库表:accounts、users和user_accounts,其中user_accounts表的复合主键为account_id与user_id。目前AdminBro只会自动识别其中一个作为主键,导致我无法在该表中创建任何记录。

我的AdminBro路由代码

import { sequelize } from '../../data/models';

import AdminBro from 'adminjs';
import AdminBroExpress from '@adminjs/express';
import AdminBroSequelize from '@adminjs/sequelize';

AdminBro.registerAdapter(AdminBroSequelize);
const adminBro = new AdminBro({
  rootPath: '/admin',
  resources: [
    {
      resource: sequelize.models.Account,
      options: {
        parent: {
          name: 'Database',
          icon: 'Api',
        },
        listProperties: [
          'id',
          'email',
          'emailVerified',
          'isPrimary',
          'password',
          'pictureUrl',
          'socialAccountId',
          'username',
        ],
      },
    },
    {
      resource: sequelize.models.User,
      options: {
        parent: {
          name: 'Database',
          icon: 'Api',
        },
        listProperties: ['id', 'enabled'],
      },
    },
    {
      resource: sequelize.models.UserAccount,
      options: {
        parent: {
          name: 'Database',
          icon: 'Api',
        },
        listProperties: ['id', 'accountId', 'userId'],
      },
    },
  ],
  branding: {
    companyName: 'API',
    logo: false,
    favicon: 'https://imagine.ai/img/favicon.ico',
    withMadeWithLove: false,
  },
});
const adminbroRouter = AdminBroExpress.buildRouter(adminBro);

export default adminbroRouter;

UserAccount 模型代码

/* eslint import/no-cycle: "off" */
import { DataTypes } from 'sequelize';
import {
  Model,
  PrimaryKey,
  Column,
  Table,
  Default,
  IsUUID,
  ForeignKey,
} from 'sequelize-typescript';
import { Account, User } from 'data/models';

@Table({
  freezeTableName: true,
  tableName: 'user_accounts',
})
export default class UserAccount extends Model {
  @ForeignKey(() => Account)
  @PrimaryKey
  @IsUUID(4)
  @Default(DataTypes.UUIDV4)
  @Column
  accountId: string;

  @ForeignKey(() => User)
  @PrimaryKey
  @IsUUID(4)
  @Default(DataTypes.UUIDV4)
  @Column
  userId: string;
}

解决方案

1. 修正列表属性的错误字段

你的UserAccount模型中没有id字段,但AdminBro配置的listProperties里包含了该字段,先移除这个错误配置:

{
  resource: sequelize.models.UserAccount,
  options: {
    parent: {
      name: 'Database',
      icon: 'Api',
    },
    listProperties: ['accountId', 'userId'], // 移除不存在的id字段
  },
}

2. 手动指定复合主键

AdminBro的Sequelize适配器无法自动识别复合主键,需要在资源配置中手动声明primaryKey为数组形式,同时配置字段的可见性与可用性:

{
  resource: sequelize.models.UserAccount,
  options: {
    parent: {
      name: 'Database',
      icon: 'Api',
    },
    listProperties: ['accountId', 'userId'],
    primaryKey: ['accountId', 'userId'], // 手动指定复合主键数组
    properties: {
      accountId: {
        isVisible: { list: true, edit: true, show: true, filter: true },
        isDisabled: true, // 模型已设置自动生成UUID,无需手动输入
      },
      userId: {
        isVisible: { list: true, edit: true, show: true, filter: true },
        isDisabled: true,
      },
    },
    createProperties: ['accountId', 'userId'], // 确保创建表单包含两个主键字段
  },
}

3. 验证模型配置

你的UserAccount模型已经通过@PrimaryKey装饰器正确标记了两个复合主键字段,这部分无需修改,AdminBro会结合手动配置的primaryKey数组正确识别复合主键结构。

4. 测试创建功能

修改配置后重启服务,进入AdminBro的UserAccount创建页面,两个主键字段会自动生成UUID(因设置了isDisabled),提交后即可成功创建复合主键的记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 16:45:42