diff --git a/.gitignore b/.gitignore
index 8d050113..250c4f26 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,6 +51,9 @@ typings/
 # Optional npm cache directory
 .npm
 
+# npm config
+.npmrc
+
 # Optional eslint cache
 .eslintcache
 
diff --git a/src/lib/PostgresMetaColumns.ts b/src/lib/PostgresMetaColumns.ts
index 07224c9c..250d7904 100644
--- a/src/lib/PostgresMetaColumns.ts
+++ b/src/lib/PostgresMetaColumns.ts
@@ -115,89 +115,101 @@ WHERE
     }
   }
 
-  async create({
-    table_id,
-    name,
-    type,
-    default_value,
-    default_value_format = 'literal',
-    is_identity = false,
-    identity_generation = 'BY DEFAULT',
-    // Can't pick a value as default since regular columns are nullable by default but PK columns aren't
-    is_nullable,
-    is_primary_key = false,
-    is_unique = false,
-    comment,
-    check,
-  }: {
-    table_id: number
-    name: string
-    type: string
-    default_value?: any
-    default_value_format?: 'expression' | 'literal'
-    is_identity?: boolean
-    identity_generation?: 'BY DEFAULT' | 'ALWAYS'
-    is_nullable?: boolean
-    is_primary_key?: boolean
-    is_unique?: boolean
-    comment?: string
-    check?: string
-  }): Promise<PostgresMetaResult<PostgresColumn>> {
+  async create(
+    columns: {
+      table_id: number
+      name: string
+      type: string
+      default_value?: any
+      default_value_format?: 'expression' | 'literal'
+      is_identity?: boolean
+      identity_generation?: 'BY DEFAULT' | 'ALWAYS'
+      is_nullable?: boolean
+      is_primary_key?: boolean
+      is_unique?: boolean
+      comment?: string
+      check?: string
+    }[]
+  ): Promise<PostgresMetaResult<PostgresColumn[]>> {
+    const { table_id } = columns[0]
+
     const { data, error } = await this.metaTables.retrieve({ id: table_id })
     if (error) {
       return { data: null, error }
     }
     const { name: table, schema } = data!
+    let sql = `BEGIN;`
+    for (const column of columns) {
+      const {
+        name,
+        type,
+        default_value,
+        default_value_format = 'literal',
+        is_identity = false,
+        identity_generation = 'BY DEFAULT',
+        // Can't pick a value as default since regular columns are nullable by default but PK columns aren't
+        is_nullable,
+        is_primary_key = false,
+        is_unique = false,
+        comment,
+        check,
+      } = column
+      sql += `
+      ALTER TABLE ${ident(schema)}.${ident(table)} ADD COLUMN ${ident(name)} ${typeIdent(type)}`
 
-    let defaultValueClause = ''
-    if (is_identity) {
-      if (default_value !== undefined) {
-        return {
-          data: null,
-          error: { message: 'Columns cannot both be identity and have a default value' },
+      let defaultValueClause = ''
+      if (is_identity) {
+        if (default_value !== undefined) {
+          return {
+            data: null,
+            error: { message: 'Columns cannot both be identity and have a default value' },
+          }
         }
-      }
 
-      defaultValueClause = `GENERATED ${identity_generation} AS IDENTITY`
-    } else {
-      if (default_value === undefined) {
-        // skip
-      } else if (default_value_format === 'expression') {
-        defaultValueClause = `DEFAULT ${default_value}`
+        defaultValueClause = `GENERATED ${identity_generation} AS IDENTITY`
       } else {
-        defaultValueClause = `DEFAULT ${literal(default_value)}`
+        if (default_value === undefined) {
+          // skip
+        } else if (default_value_format === 'expression') {
+          defaultValueClause = `DEFAULT ${default_value}`
+        } else {
+          defaultValueClause = `DEFAULT ${literal(default_value)}`
+        }
       }
-    }
 
-    let isNullableClause = ''
-    if (is_nullable !== undefined) {
-      isNullableClause = is_nullable ? 'NULL' : 'NOT NULL'
+      let isNullableClause = ''
+      if (is_nullable !== undefined) {
+        isNullableClause = is_nullable ? 'NULL' : 'NOT NULL'
+      }
+      const isPrimaryKeyClause = is_primary_key ? 'PRIMARY KEY' : ''
+      const isUniqueClause = is_unique ? 'UNIQUE' : ''
+      const checkSql = check === undefined ? '' : `CHECK (${check})`
+      const commentSql =
+        comment === undefined
+          ? ''
+          : `COMMENT ON COLUMN ${ident(schema)}.${ident(table)}.${ident(name)} IS ${literal(
+              comment
+            )}`
+
+      sql += `
+      ${defaultValueClause}
+      ${isNullableClause}
+      ${isPrimaryKeyClause}
+      ${isUniqueClause}
+      ${checkSql};
+    ${commentSql};`
     }
-    const isPrimaryKeyClause = is_primary_key ? 'PRIMARY KEY' : ''
-    const isUniqueClause = is_unique ? 'UNIQUE' : ''
-    const checkSql = check === undefined ? '' : `CHECK (${check})`
-    const commentSql =
-      comment === undefined
-        ? ''
-        : `COMMENT ON COLUMN ${ident(schema)}.${ident(table)}.${ident(name)} IS ${literal(comment)}`
 
-    const sql = `
-BEGIN;
-  ALTER TABLE ${ident(schema)}.${ident(table)} ADD COLUMN ${ident(name)} ${typeIdent(type)}
-    ${defaultValueClause}
-    ${isNullableClause}
-    ${isPrimaryKeyClause}
-    ${isUniqueClause}
-    ${checkSql};
-  ${commentSql};
-COMMIT;`
+    sql += `COMMIT;`
     {
       const { error } = await this.query(sql)
       if (error) {
         return { data: null, error }
       }
     }
-    return await this.retrieve({ name, table, schema })
+    const res = await this.list({ tableId: table_id, includedSchemas: [schema] })
+    res.data = res.data?.filter((d) => columns.find((c) => d.name === c.name)) as PostgresColumn[]
+    return res
   }
 
   async update(
diff --git a/src/server/routes/columns.ts b/src/server/routes/columns.ts
index 54a7ba2a..d640b298 100644
--- a/src/server/routes/columns.ts
+++ b/src/server/routes/columns.ts
@@ -140,9 +140,9 @@ const route: FastifyPluginAsyncTypebox = async (fastify) => {
         headers: Type.Object({
           pg: Type.String(),
         }),
-        body: postgresColumnCreateSchema,
+        body: Type.Union([postgresColumnCreateSchema, Type.Array(postgresColumnCreateSchema)]),
         response: {
-          200: postgresColumnSchema,
+          200: Type.Union([postgresColumnSchema, Type.Array(postgresColumnSchema)]),
           400: Type.Object({
             error: Type.String(),
           }),
@@ -153,7 +153,8 @@ const route: FastifyPluginAsyncTypebox = async (fastify) => {
       const connectionString = request.headers.pg
 
       const pgMeta = new PostgresMeta({ ...DEFAULT_POOL_CONFIG, connectionString })
-      const { data, error } = await pgMeta.columns.create(request.body)
+      const colMutations = Array.isArray(request.body) ? request.body : [request.body]
+      const { data, error } = await pgMeta.columns.create(colMutations)
       await pgMeta.end()
       if (error) {
         request.log.error({ error, request: extractRequestForLogging(request) })
@@ -162,7 +163,7 @@ const route: FastifyPluginAsyncTypebox = async (fastify) => {
         return { error: error.message }
       }
 
-      return data
+      return Array.isArray(request.body) ? data : data[0]
     }
   )
 
diff --git a/test/lib/columns.ts b/test/lib/columns.ts
index 59fff2bd..32d5c3e6 100644
--- a/test/lib/columns.ts
+++ b/test/lib/columns.ts
@@ -141,42 +141,46 @@ test('list columns with excluded schemas and include System Schemas', async () =
 test('retrieve, create, update, delete', async () => {
   const { data: testTable }: any = await pgMeta.tables.create({ name: 't' })
 
-  let res = await pgMeta.columns.create({
-    table_id: testTable!.id,
-    name: 'c',
-    type: 'int2',
-    default_value: 42,
-    comment: 'foo',
-  })
-  expect(res).toMatchInlineSnapshot(
-    { data: { id: expect.stringMatching(/^\d+\.1$/), table_id: expect.any(Number) } },
+  const createRes = await pgMeta.columns.create([
+    {
+      table_id: testTable!.id,
+      name: 'c',
+      type: 'int2',
+      default_value: 42,
+      comment: 'foo',
+    },
+  ])
+  expect(createRes).toMatchInlineSnapshot(
+    { data: [{ id: expect.stringMatching(/^\d+\.1$/), table_id: expect.any(Number) }] },
     `
     {
-      "data": {
-        "check": null,
-        "comment": "foo",
-        "data_type": "smallint",
-        "default_value": "'42'::smallint",
-        "enums": [],
-        "format": "int2",
-        "id": StringMatching /\\^\\\\d\\+\\\\\\.1\\$/,
-        "identity_generation": null,
-        "is_generated": false,
-        "is_identity": false,
-        "is_nullable": true,
-        "is_unique": false,
-        "is_updatable": true,
-        "name": "c",
-        "ordinal_position": 1,
-        "schema": "public",
-        "table": "t",
-        "table_id": Any<Number>,
-      },
+      "data": [
+        {
+          "check": null,
+          "comment": "foo",
+          "data_type": "smallint",
+          "default_value": "'42'::smallint",
+          "enums": [],
+          "format": "int2",
+          "id": StringMatching /\\^\\\\d\\+\\\\\\.1\\$/,
+          "identity_generation": null,
+          "is_generated": false,
+          "is_identity": false,
+          "is_nullable": true,
+          "is_unique": false,
+          "is_updatable": true,
+          "name": "c",
+          "ordinal_position": 1,
+          "schema": "public",
+          "table": "t",
+          "table_id": Any<Number>,
+        },
+      ],
       "error": null,
     }
   `
   )
-  res = await pgMeta.columns.retrieve({ id: res.data!.id })
+  let res = await pgMeta.columns.retrieve({ id: createRes.data![0].id })
   expect(res).toMatchInlineSnapshot(
     {
       data: { id: expect.stringMatching(/^\d+\.1$/), table_id: expect.any(Number) },
@@ -288,6 +292,187 @@ test('retrieve, create, update, delete', async () => {
   await pgMeta.tables.remove(testTable!.id)
 })
 
+test('create multiple columns at once', async () => {
+  const { data: testTable }: any = await pgMeta.tables.create({ name: 't' })
+
+  const createRes = await pgMeta.columns.create([
+    {
+      table_id: testTable!.id,
+      name: 'a',
+      type: 'int2',
+      default_value: 42,
+      comment: 'foo',
+    },
+    {
+      table_id: testTable!.id,
+      name: 'b',
+      type: 'int2[]',
+    },
+    {
+      table_id: testTable!.id,
+      name: 'c',
+      type: 'timestamptz',
+      default_value: 'NOW()',
+      default_value_format: 'expression',
+    },
+  ])
+  expect(createRes.error).toBeNull()
+  expect(createRes).toMatchInlineSnapshot(
+    {
+      data: [
+        { id: expect.stringMatching(/^\d+\.1$/), table_id: expect.any(Number) },
+        { id: expect.stringMatching(/^\d+\.2$/), table_id: expect.any(Number) },
+        { id: expect.stringMatching(/^\d+\.3$/), table_id: expect.any(Number) },
+      ],
+    },
+    `
+    {
+      "data": [
+        {
+          "check": null,
+          "comment": "foo",
+          "data_type": "smallint",
+          "default_value": "'42'::smallint",
+          "enums": [],
+          "format": "int2",
+          "id": StringMatching /\\^\\\\d\\+\\\\\\.1\\$/,
+          "identity_generation": null,
+          "is_generated": false,
+          "is_identity": false,
+          "is_nullable": true,
+          "is_unique": false,
+          "is_updatable": true,
+          "name": "a",
+          "ordinal_position": 1,
+          "schema": "public",
+          "table": "t",
+          "table_id": Any<Number>,
+        },
+        {
+          "check": null,
+          "comment": null,
+          "data_type": "ARRAY",
+          "default_value": null,
+          "enums": [],
+          "format": "_int2",
+          "id": StringMatching /\\^\\\\d\\+\\\\\\.2\\$/,
+          "identity_generation": null,
+          "is_generated": false,
+          "is_identity": false,
+          "is_nullable": true,
+          "is_unique": false,
+          "is_updatable": true,
+          "name": "b",
+          "ordinal_position": 2,
+          "schema": "public",
+          "table": "t",
+          "table_id": Any<Number>,
+        },
+        {
+          "check": null,
+          "comment": null,
+          "data_type": "timestamp with time zone",
+          "default_value": "now()",
+          "enums": [],
+          "format": "timestamptz",
+          "id": StringMatching /\\^\\\\d\\+\\\\\\.3\\$/,
+          "identity_generation": null,
+          "is_generated": false,
+          "is_identity": false,
+          "is_nullable": true,
+          "is_unique": false,
+          "is_updatable": true,
+          "name": "c",
+          "ordinal_position": 3,
+          "schema": "public",
+          "table": "t",
+          "table_id": Any<Number>,
+        },
+      ],
+      "error": null,
+    }
+  `
+  )
+  let res = await pgMeta.columns.list({ tableId: testTable.id })
+  expect(res).toMatchInlineSnapshot(
+    {
+      data: [
+        { id: expect.stringMatching(/^\d+\.1$/), table_id: expect.any(Number) },
+        { id: expect.stringMatching(/^\d+\.2$/), table_id: expect.any(Number) },
+        { id: expect.stringMatching(/^\d+\.3$/), table_id: expect.any(Number) },
+      ],
+    },
+    `
+    {
+      "data": [
+        {
+          "check": null,
+          "comment": "foo",
+          "data_type": "smallint",
+          "default_value": "'42'::smallint",
+          "enums": [],
+          "format": "int2",
+          "id": StringMatching /\\^\\\\d\\+\\\\\\.1\\$/,
+          "identity_generation": null,
+          "is_generated": false,
+          "is_identity": false,
+          "is_nullable": true,
+          "is_unique": false,
+          "is_updatable": true,
+          "name": "a",
+          "ordinal_position": 1,
+          "schema": "public",
+          "table": "t",
+          "table_id": Any<Number>,
+        },
+        {
+          "check": null,
+          "comment": null,
+          "data_type": "ARRAY",
+          "default_value": null,
+          "enums": [],
+          "format": "_int2",
+          "id": StringMatching /\\^\\\\d\\+\\\\\\.2\\$/,
+          "identity_generation": null,
+          "is_generated": false,
+          "is_identity": false,
+          "is_nullable": true,
+          "is_unique": false,
+          "is_updatable": true,
+          "name": "b",
+          "ordinal_position": 2,
+          "schema": "public",
+          "table": "t",
+          "table_id": Any<Number>,
+        },
+        {
+          "check": null,
+          "comment": null,
+          "data_type": "timestamp with time zone",
+          "default_value": "now()",
+          "enums": [],
+          "format": "timestamptz",
+          "id": StringMatching /\\^\\\\d\\+\\\\\\.3\\$/,
+          "identity_generation": null,
+          "is_generated": false,
+          "is_identity": false,
+          "is_nullable": true,
+          "is_unique": false,
+          "is_updatable": true,
+          "name": "c",
+          "ordinal_position": 3,
+          "schema": "public",
+          "table": "t",
+          "table_id": Any<Number>,
+        },
+      ],
+      "error": null,
+    }
+  `
+  )
+  await pgMeta.tables.remove(testTable!.id)
+})
+
 test('enum column with quoted name', async () => {
   await pgMeta.query('CREATE TYPE "T" AS ENUM (\'v\'); CREATE TABLE t ( c "T" );')
 
@@ -329,12 +514,14 @@ test('enum column with quoted name', async () => {
 test('primary key column', async () => {
   const { data: testTable } = await pgMeta.tables.create({ name: 't' })
 
-  await pgMeta.columns.create({
-    table_id: testTable!.id,
-    name: 'c',
-    type: 'int2',
-    is_primary_key: true,
-  })
+  await pgMeta.columns.create([
+    {
+      table_id: testTable!.id,
+      name: 'c',
+      type: 'int2',
+      is_primary_key: true,
+    },
+  ])
   const res = await pgMeta.query(`
 SELECT a.attname
 FROM   pg_index i
@@ -360,12 +547,14 @@ AND    i.indisprimary;
 test('unique column', async () => {
   const { data: testTable } = await pgMeta.tables.create({ name: 't' })
 
-  await pgMeta.columns.create({
-    table_id: testTable!.id,
-    name: 'c',
-    type: 'int2',
-    is_unique: true,
-  })
+  await pgMeta.columns.create([
+    {
+      table_id: testTable!.id,
+      name: 'c',
+      type: 'int2',
+      is_unique: true,
+    },
+  ])
   const res = await pgMeta.query(`
 SELECT a.attname
 FROM   pg_index i
@@ -392,40 +581,46 @@ AND    i.indisunique;
 test('array column', async () => {
   const { data: testTable } = await pgMeta.tables.create({ name: 't' })
 
-  const res = await pgMeta.columns.create({
-    table_id: testTable!.id,
-    name: 'c',
-    type: 'int2[]',
-  })
+  const res = await pgMeta.columns.create([
+    {
+      table_id: testTable!.id,
+      name: 'c',
+      type: 'int2[]',
+    },
+  ])
   expect(res).toMatchInlineSnapshot(
     {
-      data: {
-        id: expect.stringMatching(/^\d+\.1$/),
-        table_id: expect.any(Number),
-      },
+      data: [
+        {
+          id: expect.stringMatching(/^\d+\.1$/),
+          table_id: expect.any(Number),
+        },
+      ],
     },
     `
     {
-      "data": {
-        "check": null,
-        "comment": null,
-        "data_type": "ARRAY",
-        "default_value": null,
-        "enums": [],
-        "format": "_int2",
-        "id": StringMatching /\\^\\\\d\\+\\\\\\.1\\$/,
-        "identity_generation": null,
-        "is_generated": false,
-        "is_identity": false,
-        "is_nullable": true,
-        "is_unique": false,
-        "is_updatable": true,
-        "name": "c",
-        "ordinal_position": 1,
-        "schema": "public",
-        "table": "t",
-        "table_id": Any<Number>,
-      },
+      "data": [
+        {
+          "check": null,
+          "comment": null,
+          "data_type": "ARRAY",
+          "default_value": null,
+          "enums": [],
+          "format": "_int2",
+          "id": StringMatching /\\^\\\\d\\+\\\\\\.1\\$/,
+          "identity_generation": null,
+          "is_generated": false,
+          "is_identity": false,
+          "is_nullable": true,
+          "is_unique": false,
+          "is_updatable": true,
+          "name": "c",
+          "ordinal_position": 1,
+          "schema": "public",
+          "table": "t",
+          "table_id": Any<Number>,
+        },
+      ],
       "error": null,
     }
   `
@@ -437,42 +632,48 @@ test('array column', async () => {
 test('column with default value', async () => {
   const { data: testTable } = await pgMeta.tables.create({ name: 't' })
 
-  const res = await pgMeta.columns.create({
-    table_id: testTable!.id,
-    name: 'c',
-    type: 'timestamptz',
-    default_value: 'NOW()',
-    default_value_format: 'expression',
-  })
+  const res = await pgMeta.columns.create([
+    {
+      table_id: testTable!.id,
+      name: 'c',
+      type: 'timestamptz',
+      default_value: 'NOW()',
+      default_value_format: 'expression',
+    },
+  ])
   expect(res).toMatchInlineSnapshot(
     {
-      data: {
-        id: expect.stringMatching(/^\d+\.1$/),
-        table_id: expect.any(Number),
-      },
+      data: [
+        {
+          id: expect.stringMatching(/^\d+\.1$/),
+          table_id: expect.any(Number),
+        },
+      ],
     },
     `
     {
-      "data": {
-        "check": null,
-        "comment": null,
-        "data_type": "timestamp with time zone",
-        "default_value": "now()",
-        "enums": [],
-        "format": "timestamptz",
-        "id": StringMatching /\\^\\\\d\\+\\\\\\.1\\$/,
-        "identity_generation": null,
-        "is_generated": false,
-        "is_identity": false,
-        "is_nullable": true,
-        "is_unique": false,
-        "is_updatable": true,
-        "name": "c",
-        "ordinal_position": 1,
-        "schema": "public",
-        "table": "t",
-        "table_id": Any<Number>,
-      },
+      "data": [
+        {
+          "check": null,
+          "comment": null,
+          "data_type": "timestamp with time zone",
+          "default_value": "now()",
+          "enums": [],
+          "format": "timestamptz",
+          "id": StringMatching /\\^\\\\d\\+\\\\\\.1\\$/,
+          "identity_generation": null,
+          "is_generated": false,
+          "is_identity": false,
+          "is_nullable": true,
+          "is_unique": false,
+          "is_updatable": true,
+          "name": "c",
+          "ordinal_position": 1,
+          "schema": "public",
+          "table": "t",
+          "table_id": Any<Number>,
+        },
+      ],
       "error": null,
     }
   `
@@ -484,12 +685,14 @@ test('column with default value', async () => {
 test('column with constraint', async () => {
   const { data: testTable } = await pgMeta.tables.create({ name: 't' })
 
-  await pgMeta.columns.create({
-    table_id: testTable!.id,
-    name: 'c',
-    type: 'text',
-    check: "description <> ''",
-  })
+  await pgMeta.columns.create([
+    {
+      table_id: testTable!.id,
+      name: 'c',
+      type: 'text',
+      check: "description <> ''",
+    },
+  ])
   const res = await pgMeta.query(`
 SELECT pg_get_constraintdef((
   SELECT c.oid
@@ -514,12 +717,14 @@ SELECT pg_get_constraintdef((
 test('update with name unchanged', async () => {
   const { data: testTable } = await pgMeta.tables.create({ name: 't' })
 
-  let res = await pgMeta.columns.create({
-    table_id: testTable!.id,
-    name: 'c',
-    type: 'int2',
-  })
-  res = await pgMeta.columns.update(res.data!.id, {
+  let createRes = await pgMeta.columns.create([
+    {
+      table_id: testTable!.id,
+      name: 'c',
+      type: 'int2',
+    },
+  ])
+  let res = await pgMeta.columns.update(createRes.data![0].id, {
     name: 'c',
   })
   expect(res).toMatchInlineSnapshot(
@@ -562,12 +767,14 @@ test('update with name unchanged', async () => {
 test('update with array types', async () => {
   const { data: testTable } = await pgMeta.tables.create({ name: 't' })
 
-  let res = await pgMeta.columns.create({
-    table_id: testTable!.id,
-    name: 'c',
-    type: 'text',
-  })
-  res = await pgMeta.columns.update(res.data!.id, {
+  let createRes = await pgMeta.columns.create([
+    {
+      table_id: testTable!.id,
+      name: 'c',
+      type: 'text',
+    },
+  ])
+  let res = await pgMeta.columns.update(createRes.data![0].id, {
     type: 'text[]',
   })
   expect(res).toMatchInlineSnapshot(
@@ -610,12 +817,14 @@ test('update with array types', async () => {
 test('update with incompatible types', async () => {
   const { data: testTable } = await pgMeta.tables.create({ name: 't' })
 
-  let res = await pgMeta.columns.create({
-    table_id: testTable!.id,
-    name: 'c',
-    type: 'text',
-  })
-  res = await pgMeta.columns.update(res.data!.id, {
+  let createRes = await pgMeta.columns.create([
+    {
+      table_id: testTable!.id,
+      name: 'c',
+      type: 'text',
+    },
+  ])
+  let res = await pgMeta.columns.update(createRes.data![0].id, {
     type: 'int4',
   })
   expect(res).toMatchInlineSnapshot(
@@ -658,13 +867,15 @@ test('update with incompatible types', async () => {
 test('update is_unique', async () => {
   const { data: testTable } = await pgMeta.tables.create({ name: 't' })
 
-  let res = await pgMeta.columns.create({
-    table_id: testTable!.id,
-    name: 'c',
-    type: 'text',
-    is_unique: false,
-  })
-  res = await pgMeta.columns.update(res.data!.id, { is_unique: true })
+  let createRes = await pgMeta.columns.create([
+    {
+      table_id: testTable!.id,
+      name: 'c',
+      type: 'text',
+      is_unique: false,
+    },
+  ])
+  let res = await pgMeta.columns.update(createRes.data![0].id, { is_unique: true })
   expect(res).toMatchInlineSnapshot(
     {
       data: {
@@ -741,13 +952,15 @@ test('alter column to type with uppercase', async () => {
   const { data: testTable } = await pgMeta.tables.create({ name: 't' })
   await pgMeta.query('CREATE TYPE "T" AS ENUM ()')
 
-  let res = await pgMeta.columns.create({
-    table_id: testTable!.id,
-    name: 'c',
-    type: 'text',
-    is_unique: false,
-  })
-  res = await pgMeta.columns.update(res.data!.id, { type: 'T' })
+  let createRes = await pgMeta.columns.create([
+    {
+      table_id: testTable!.id,
+      name: 'c',
+      type: 'text',
+      is_unique: false,
+    },
+  ])
+  let res = await pgMeta.columns.update(createRes.data![0].id, { type: 'T' })
   expect(res).toMatchInlineSnapshot(
     {
       data: {
@@ -790,42 +1003,48 @@ test('enums are populated in enum array columns', async () => {
   await pgMeta.query(`create type test_enum as enum ('a')`)
   const { data: testTable } = await pgMeta.tables.create({ name: 't' })
 
-  let res = await pgMeta.columns.create({
-    table_id: testTable!.id,
-    name: 'c',
-    type: '_test_enum',
-  })
+  let res = await pgMeta.columns.create([
+    {
+      table_id: testTable!.id,
+      name: 'c',
+      type: '_test_enum',
+    },
+  ])
   expect(res).toMatchInlineSnapshot(
     {
-      data: {
-        id: expect.stringMatching(/^\d+\.1$/),
-        table_id: expect.any(Number),
-      },
+      data: [
+        {
+          id: expect.stringMatching(/^\d+\.1$/),
+          table_id: expect.any(Number),
+        },
+      ],
     },
     `
     {
-      "data": {
-        "check": null,
-        "comment": null,
-        "data_type": "ARRAY",
-        "default_value": null,
-        "enums": [
-          "a",
-        ],
-        "format": "_test_enum",
-        "id": StringMatching /\\^\\\\d\\+\\\\\\.1\\$/,
-        "identity_generation": null,
-        "is_generated": false,
-        "is_identity": false,
-        "is_nullable": true,
-        "is_unique": false,
-        "is_updatable": true,
-        "name": "c",
-        "ordinal_position": 1,
-        "schema": "public",
-        "table": "t",
-        "table_id": Any<Number>,
-      },
+      "data": [
+        {
+          "check": null,
+          "comment": null,
+          "data_type": "ARRAY",
+          "default_value": null,
+          "enums": [
+            "a",
+          ],
+          "format": "_test_enum",
+          "id": StringMatching /\\^\\\\d\\+\\\\\\.1\\$/,
+          "identity_generation": null,
+          "is_generated": false,
+          "is_identity": false,
+          "is_nullable": true,
+          "is_unique": false,
+          "is_updatable": true,
+          "name": "c",
+          "ordinal_position": 1,
+          "schema": "public",
+          "table": "t",
+          "table_id": Any<Number>,
+        },
+      ],
       "error": null,
     }
   `
diff --git a/test/lib/tables.ts b/test/lib/tables.ts
index ae3dfe97..697af678 100644
--- a/test/lib/tables.ts
+++ b/test/lib/tables.ts
@@ -401,8 +401,10 @@ test("allow ' in comments", async () => {
 
 test('primary keys', async () => {
   let res = await pgMeta.tables.create({ name: 't' })
-  await pgMeta.columns.create({ table_id: res.data!.id, name: 'c', type: 'int8' })
-  await pgMeta.columns.create({ table_id: res.data!.id, name: 'cc', type: 'text' })
+  await pgMeta.columns.create([
+    { table_id: res.data!.id, name: 'c', type: 'int8' },
+    { table_id: res.data!.id, name: 'cc', type: 'text' },
+  ])
   res = await pgMeta.tables.update(res.data!.id, {
     primary_keys: [{ name: 'c' }, { name: 'cc' }],
   })