SQLAlchemy完整性错误:重复键违反唯一约束条件

3
这个问题已经困扰我很久了,但我在其他问题中找不到任何解决方案。
在SQLAlchemy中,我正在创建一个由2个表链接的模式。当我向这些表中插入数据时,会出现唯一约束错误:
    (IntegrityError) ERROR:  duplicate key violates UNIQUE-CONSTRAINT e_data_pkey
    DETAIL:  KEY (id)=(2) already exists.
    'INSERT INTO e_data (id, iso3, year, value) VALUES (%(id)s, %(iso3)s, %(year)s, %(value)s)' 
  ({'iso3': 'ABW', 'id': 1, 'value': 5.5, 'year': 2009}, 
   {'iso3': 'ZZZ', **'id': 2,** 'value': 9.9, 'year': 1977}, 
   {'iso3': 'ZZY', **'id': 2**, 'value': 9.876, 'year': 1971})

很明显,该类在列表中为每个实例分配相同的ID。 SQLAlchemy是否应该自动生成ID?为什么会出现此错误?我从其他来源调整了此示例,因此应该很容易实施。有人看到问题了吗?这是我正在使用的代码:
from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relation, sessionmaker

Base = declarative_base()

class E_data(Base):
    __tablename__ = 'e_data'

    id = Column(Integer, ForeignKey('e_indicator.id'), primary_key=True) 
    iso3 = Column(String(3), nullable=False)
    year = Column(Integer)
    value = Column(FLOAT)

    eind = relation("E_indicator", backref='e_data', lazy=False)

    def __init__(self, iso3=None, year=None, value=None):
        self.iso3 = iso3
        self.year = year
        self.value = value
    def __repr__(self):
        return "E_Data (%r, %r, %r, %r)" % (self.iso3, self.year, self.value, self.eind)

class E_indicator(Base):
    __tablename__ = 'e_indicator'

    id = Column(Integer, primary_key=True)
    name = Column(String(50), nullable=False, unique=True)

    def __init__(self, name=None):
        self.name = name

    def __repr__(self):
        return "E_indicator (%r)" % (self.name)

engine = create_engine('postgresql://postgres:password@localhost/world')
Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

#INSERT INTO DB
Session = sessionmaker(bind=engine)
session = Session()

m1 = E_data("ABW", 2009, 5.5)
m1.eind = E_indicator("GDP_TEST")

d2 = E_indicator("GDP THE OTHER WAY ROUND")
d2.e_data = [E_data("ZZZ", 1977, 9.9), E_data("ZZY", 1971, 9.876)]


#try:
session.add(m1)
session.add(d2)
session.commit()
#except:
    #session.rollback()

感谢任何建议。
3个回答

3
抱歉,您所提供的建议均未解决我的问题。唯一有效的方法是指定类似于以下条件的主连接(primaryjoin):
eind = relation("E_indicator", backref='e_data', primaryjoin="E_indicator.id==E_data.id")

这解决了问题。希望能对某些人有所帮助。 祝好,A

1
然后,将你的答案标记为正确解决方案非常重要! - Noki

0
我的问题是当应用程序第一次运行时,我插入了4条初始记录。不知何故,Postgres重新启动了计数器,我仍然不知道为什么,在第5次尝试和以后的每次尝试中它都能正常工作。

-6
这是因为您在 E_data 表中将外键列 id 声明为 primary key
只需删除 id 列的 primary_key=True 即可。
class E_data(Base):
    __tablename__ = 'e_data'

    e_data_id = Column(Integer, primary_key=True)
    e_indicator_id = Column(Integer, ForeignKey('e_indicator.id'))
    iso3.........

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接