PostgreSQL false IntegrityError

时间:2017-02-22 15:50:17

标签: postgresql psycopg2

无法找到解决方案。我现在传递一个元组列表,其中包含要插入的信息,而不是从另一个表中提取,问题就消失了。

我目前正在编写将编辑表格的代码。我有几行要插入的信息但我不断在第四个元素上获得IntegrityError,无论顺序如何。

以下是我创建表格的方法:

CREATE TABLE segment_speed_live_layer(segment_id INTEGER PRIMARY KEY,
                                      geom GEOMETRY(LINESTRING, 4326), 
                                      speed INTEGER);

现在,segment_id必须与另一个表匹配,因此它不是也不能是顺序的。这是功能:

def update_layer():
    segment_cursor = connection.cursor()
    segment_query = 'SELECT segment_id, speed FROM segment_speed_live ORDER BY segment_id'
    exists_cursor = connection.cursor()
    exists_query = 'SELECT EXISTS(SELECT 1 FROM segment_speed_live_layer WHERE segment_id=%s)'
    insert_cursor = connection.cursor()
    insert_query = """INSERT INTO segment_speed_live_layer(segment_id, geom, speed)
                      SELECT %(segment_id)s, geom_way, %(speed)s
                      FROM other_table
                      WHERE segment_id=%(segment_id)s"""
    update_query = 'UPDATE segment_speed_live_layer SET speed=%(speed)s WHERE segment_id=%(segment_id)s'
    segment_cursor.execute(segment_query)
    for row in segment_cursor:
        segment_id, speed = row
        exists_cursor.execute(exists_query, (segment_id, ))
        exists = exists_cursor.fetchone()[0]
        query = update_query if exists else insert_query
        print(segment_id, speed, exists)
        print(insert_cursor.mogrify(query, {'segment_id': segment_id, 'speed': speed}))
        insert_cursor.execute(query, {'segment_id': segment_id, 'speed': speed})
        print(insert_cursor.statusmessage)
    connection.commit()

如果我按速度订购,它会在第五个而不是第四个元素上失败。它似乎在较低的ID上失败了。这是测试阶段,因此我已多次删除并重新创建表,KNOW此表中没有包含给定ID的行。

我已阅读this questionthis blog post,但他们的解决方案不起作用,因为我的ID未按顺序或自动分配。

我目前唯一的想法是删除PRIMARY KEY约束,但这并不理想。

输出参考:

(243, 69, False)
INSERT INTO segment_speed_live_layer(segment_id, geom, speed)
                      SELECT 243, geom_way, 69
                      FROM other_table
                      WHERE other_table.segment_id=243
INSERT 0 1
(680, 9, False)
INSERT INTO segment_speed_live_layer(segment_id, geom, speed)
                      SELECT 680, geom_way, 9
                      FROM other_table
                      WHERE other_table.segment_id=680
INSERT 0 1
(11599, 42, False)
INSERT INTO segment_speed_live_layer(segment_id, geom, speed)
                      SELECT 11599, geom_way, 42
                      FROM other_table
                      WHERE other_table.segment_id=11599
INSERT 0 1
(16399, 40, False)
INSERT INTO segment_speed_live_layer(segment_id, geom, speed)
                      SELECT 16399, geom_way, 40
                      FROM other_table
                      WHERE other_table.segment_id=16399

1 个答案:

答案 0 :(得分:0)

立刻完成所有工作:

with u as (
    update segment_speed_live_layer ssll
    set speed = ssl.speed
    from segment_speed_live ssl
    where ssl.segment_id = ssll.segment_id
)
insert into segment_speed_live_layer (segment_id, geom, speed)
select segment_id, geom_way, speed
from
    other_table ot
    cross join
    segment_speed_live ssl
where not exists (
    select 1
    from segment_speed_live_layer
    where segment_id = ssl.segment_id
)