InternalError:当前事务中止,在事务块结束时忽略命令,在UNIQUE约束上

时间:2017-12-08 03:05:14

标签: python-3.x postgresql psycopg2

我试图用我的except:语句执行...同时试图反对UNIQUE约束的功能..但是以异常错误结束了... Postgresql数据库表已包含我在

中使用的行
  

db.insert(" The News"," AparnaKumar",1995,234569654)

但它在插入未重复的行时效果很好..

import psycopg2
class database:

    def __init__(self):

        self.con=psycopg2.connect("dbname='book_store' user='postgres' password='5283' host='localhost' port='5432' ")
        self.cur=self.con.cursor()
        self.cur.execute("CREATE TABLE if not exists books(id SERIAL PRIMARY KEY,title TEXT NOT NULL UNIQUE,author TEXT NOT NULL,year integer NOT NULL,isbn integer NOT NULL UNIQUE)")
        self.con.commit()

    def insert(self,title,author,year,isbn):
      try:
        self.cur.execute("INSERT INTO books(title,author,year,isbn) VALUES(%s,%s,%s,%s)",(title,author,year,isbn))
        self.con.commit()
      except:
          print("already exists..")

    def view(self):
        self.cur.execute("SELECT * FROM books")
        rows=self.cur.fetchall()
        print(rows)

    def search(self,title=None,author=None,year=None,isbn=None):
        self.cur.execute("SELECT * FROM books WHERE title=%s or author=%s or year=%s or isbn=%s",(title,author,year,isbn))
        row=self.cur.fetchall()
        print(row)

db=database()
db.insert("The News","AparnaKumar",1995,234569654)
db.view()
db.search(year=1995)

InternalError: current transaction is aborted, commands ignored until end of transaction block

3 个答案:

答案 0 :(得分:4)

您可以修改python函数以回滚事务,或修改sql以在发生冲突时不插入新行(postgresql版本9.5 +):

选项1:

def insert(self,title,author,year,isbn):
  try:
    self.cur.execute("INSERT INTO books(title,author,year,isbn) VALUES(%s,%s,%s,%s)",(title,author,year,isbn))
    self.con.commit()
  except:
    self.con.rollback()
      print("already exists..")

选项2(适用于postgresql 9.5或更高版本):

def insert(self,title,author,year,isbn):
  try:
    self.cur.execute("INSERT INTO books(title,author,year,isbn) VALUES(%s,%s,%s,%s) ON CONFLICT DO NOTHING",(title,author,year,isbn))
    self.con.commit()
  except:
      print("already exists..")

答案 1 :(得分:0)

使用SAVEPOINT

请参阅psycopg FAQ list中的第二个问题。

答案 2 :(得分:0)

如果要保持事务处于打开状态,则应在发生异常时对SAVEPOINT使用SAVEPOINT和ROLLBACK。但是,由于您使用了一个catchall异常(太宽泛),这也会发生在其他错误上。所以它有点失控。

如果您要插入的记录已经存在,也许一个非常简单的解决方案是使用SELECT进行检查。