Python3 中的 PostgreSQL - 使用外键创建 table 语句中的语法错误

PostgreSQL in Python3 - SyntaxError in a create table statement with foreign key

我正在尝试创建一个 table (basic_totals),其中包含指向另一个 table(玩家)的主键的外键。我将语句保存在一个字符串中,如下所示:

player_table_name = "players"
basic_table_name = "basic_totals"
basic_table_statement = '''
    CREATE TABLE IF NOT EXISTS public.{0} (
        id SERIAL PRIMARY KEY,
        player_id SERIAL REFERENCES {1}(id),
        GP SMALLINT,
        3PTA SMALLINT,
        3PTM SMALLINT,
        FGA SMALLINT,
        FGM SMALLINT,
        FTA SMALLINT,
        FTM SMALLINT,
        PTS SMALLINT,
        FTM SMALLINT,
        PTS SMALLINT,
        REB SMALLINT,
        AST SMALLINT,
        STL SMALLINT,
        BLK SMALLINT,
        TO SMALLINT
    );'''.format(basic_table_name, player_table_name)

当尝试使用连接的游标 (cursor.execute(basic_table_statement)) 执行此语句时,会引发 SyntaxError。 由于其他table(玩家)的创建语句以相同的方式完成(减去外键部分),我假设错误在这部分附近。

我的语法有什么问题,我该如何进一步调试它?

TO 是一个 reserved keyword. If you really insist on using it, you need to use double quotes 来逃避它,例如"to"

但是一旦你这样做了,名字就会变成 sensitive,所以 TO"TO" 是不同的名字(因为 TO 是折叠成小写)。

但是,使用带引号的标识符是 strongly discouraged 并且我 高度 建议您找到一个不需要引号的不同列名称。

另一个问题是列名 3PTA3PTM。标识符不能以数字开头,因此您还需要为它们找到一个不同的名称(除非您想使用那些可怕的双引号)。

内联 REFERENCES 子句不需要重复目标 table 的主键列。您还两次定义了列 FTMPTS

不是错误的原因,而是另一个错误的选择是 player_id 的类型 serialserial 不是数据类型。它是 integer 列的缩写,它从序列中获取默认值。永远不要将外键列定义为序列,因为它们引用已经生成的值。所以应该是player_id integer REFERENCES {1}(id),

将所有这些放在一起,SQL 应该如下所示:

CREATE TABLE IF NOT EXISTS some_table (
    id serial primary key,
    player_id integer references other_table,
    gp smallint,
    pta3 smallint, --<< here
    ptm3 smallint, --<< here
    fga smallint,
    fgm smallint,
    fta smallint, 
    ftm smallint,  --<< only once!
    pts smallint,  --<< only once!
    reb smallint,
    ast smallint,
    stl smallint,
    blk smallint,
    to_x smallint  --<< change here
);