如何在旧数据库中采用 PostgreSQL 命名约定?

Eva*_*oll 1 postgresql identifier

我意识到我需要更新查询,但如果我有一个包含camelCase空格的数据库,则必须在标识符上使用双引号(即架构、表、列)。我如何摆脱考虑到我的标识符中不能有大写字母或空格。我需要将它们全部标准化为Snake_case

Eva*_*oll 5

转向 PostgreSQL 约定

在 PostgreSQL 中,按照惯例并且有充分的理由,我们在标识符(列、表、模式等)中既不使用空格也不使用大写字母。不过,使用_纯粹是风格。在这个例子中,我们

  1. 全部音译' ''_'
  2. 迁移自camelCasesnake_case

此代码没有更改任何内容,但输出相应的ALTER命令来更新架构(包括架构、表和列名称)

-- Columns first.
SELECT FORMAT(
  'ALTER TABLE %I.%I.%I RENAME COLUMN %I TO %I;',
  table_catalog,
  table_schema,
  table_name,
  column_name,
  lower(
    -- replace all spaces with _, xX and Xx becomes x_x
    regexp_replace(
      -- First, replace spaces with an _
      replace(column_name, ' ', '_'),
      '([[:lower:]])([[:upper:]])',
      '\1_\2',
      'g'
    )
  )
)
FROM information_schema.columns
WHERE column_name ~ ' |[[:lower:]][[:upper:]]'

-- Tables
UNION ALL
  SELECT FORMAT (
    'ALTER TABLE %I.%I.%I RENAME TO %I;', 
    table_catalog,
    table_schema,
    table_name,
    lower(
      regexp_replace(
        replace(table_name, ' ', '_'),
        '([[:lower:]])([[:upper:]])',
        '\1_\2',
        'g'
      )
    )
  )
  FROM information_schema.tables
  WHERE table_name ~ ' |[[:lower:]][[:upper:]]'

-- Schemas
UNION ALL
  SELECT FORMAT (
    'ALTER SCHEMA %I RENAME TO %I;',
    schema_name,
    lower(
      regexp_replace(
        replace(schema_name, ' ', '_'),
        '([[:lower:]])([[:upper:]])',
        '\1_\2',
        'g'
      )
    )
  )
  FROM information_schema.schemata
  WHERE schema_name ~ ' |[[:lower:]][[:upper:]]'; 
Run Code Online (Sandbox Code Playgroud)

从那里您可以编辑要运行的命令,删除不需要的命令,或者如果您使用 psql并且它们将执行\gexec,则只需运行即可。

测试

如果您愿意,可以测试以上内容

CREATE SCHEMA "myFoo bar";
CREATE TABLE "myFoo bar"."foo bar myBaz" ( "my foo" int, "myBar" int, "MyBaz" text, "myFooBarBaz" int, "MyFoo Bar Baz" int, "myTestQ" uuid );

                                            format                                             
-----------------------------------------------------------------------------------------------
 ALTER TABLE test.my_foo_bar.foo_bar_my_baz RENAME COLUMN "MyFoo Bar Baz" TO my_foo_bar_baz;
 ALTER TABLE test."myFoo bar"."foo bar myBaz" RENAME COLUMN "my foo" TO my_foo;
 ALTER TABLE test."myFoo bar"."foo bar myBaz" RENAME COLUMN "myBar" TO my_bar;
 ALTER TABLE test."myFoo bar"."foo bar myBaz" RENAME COLUMN "MyBaz" TO my_baz;
 ALTER TABLE test."myFoo bar"."foo bar myBaz" RENAME COLUMN "myFooBarBaz" TO my_foo_bar_baz;
 ALTER TABLE test."myFoo bar"."foo bar myBaz" RENAME COLUMN "MyFoo Bar Baz" TO my_foo_bar_baz;
 ALTER TABLE test."myFoo bar"."foo bar myBaz" RENAME COLUMN "myTestQ" TO my_test_q;
 ALTER TABLE test."myFoo bar"."foo bar myBaz" RENAME TO foo_bar_my_baz;
 ALTER SCHEMA "myFoo bar" RENAME TO my_foo_bar;
(9 rows)
Run Code Online (Sandbox Code Playgroud)

注意,因为上面的 to 中有一个碰撞my_foo_bar_baz,你会看到

错误:关系“foo bar myBaz”的列“my_foo_bar_baz”已存在

这只是证实,如果你碰巧遇到这种情况,不会发生灾难性的事情。不大可能