'SQLAlchemy duplicate key value violates unique when using association object
I have an association object defined using SQLAlchemy to represent a many-to-many relationship between 2 tables. The reason I am using the association object pattern is because the association table contains extra columns. I have a unique constraint on the name column in the data_type table. When I try to insert data into source_key, and create the relationships, it results in the error below. My question is, how would I say, "Get the ID if it exists and add to association table; otherwise, create the record in data_type, then add to association table"?
error
the-librarian-backend-1 | sqlalchemy.exc.IntegrityError: (psycopg2.errors.UniqueViolation) duplicate key value violates unique constraint "ix_data_type_name"
the-librarian-backend-1 | DETAIL: Key (name)=(str) already exists.
the-librarian-backend-1 |
the-librarian-backend-1 | [SQL: INSERT INTO data_type (name) VALUES (%(name)s) RETURNING data_type.id]
the-librarian-backend-1 | [parameters: ({'name': 'str'}, {'name': 'str'}, {'name': 'str'}, {'name': 'str'}, {'name': 'str'}, {'name': 'date'}, {'name': 'list'}, {'name': 'int'} ... displaying 10 of 747 total bound parameter sets ... {'name': 'date'}, {'name': 'str'})]
models
# source_key.py
class SourceKey(Base):
__tablename__ = 'source_key'
id = Column(Integer, primary_key=True, index=True)
source_id = Column(Integer, ForeignKey('source.id'), nullable=False)
key_id = Column(Integer, ForeignKey('key.id'), nullable=False)
description = Column(Text)
data_types = relationship("SourceKeyDataType", back_populates="source_keys")
# data_type.py
class DataType(Base):
__tablename__ = 'data_type'
id = Column(Integer, primary_key=True, index=True)
name = Column(Text, index=True, nullable=False, unique=True)
source_keys = relationship("SourceKeyDataType", back_populates="data_types")
# Association Object
class SourceKeyDataType(Base):
__tablename__ = 'source_key_data_type_assoc'
source_key_id = Column(ForeignKey('source_key.id'), primary_key=True)
data_type_id = Column(ForeignKey('data_type.id'), primary_key=True)
count = Column(BigInteger)
source_keys = relationship("SourceKey", back_populates="data_types")
data_types = relationship("DataType", back_populates="source_keys")
code
source_keys = [
{
"key": {
"name": "total"
},
"description": "the total cost of all items",
"data_types": [
{
"name": "str",
"count": 1904165
}
]
},
{
"key": {
"name": "item_value"
},
"description": "the cost of a single item",
"data_types": [
{
"name": "str",
"count": 2079817
}
]
}
]
for source_key in source_keys:
source_key_obj = {k: v for k, v in item.items() if isinstance(v, (str, int, bool, float))}
source_key_db_obj = SourceKey(**source_key_obj)
for dt in source_key.get("data_types") or []:
a = SourceKeyDataType(is_inferred=item.get("is_inferred", False), count=item.get("count", 0))
a.data_types = models.DataType(name=item["name"])
source_key_db_obj.data_types.append(a)
db.add(source_key_db_obj)
db.commit()
db.refresh(source_key_db_obj)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
