I would like to change a primary key's value, to be deterministic, based on
a multi-to-multi relation. Thus I'm populating the tables with a temporary
ids (just random strings), then calculating the right, unique id, and
changing it afterwards.
I have the following models:
class Image(Base):
id = Column(String, primary_key=True, default=lambda: random_string(16))
collections = relationship('Collection', secondary='collections_images',
back_populates='images')
class Collection(Base):
id = Column(String, primary_key=True, default=lambda: random_string(16))
images = relationship('Image', secondary='collections_images',
back_populates='collections', order_by='desc(Image.date_created)',
lazy='dynamic')
Table('collections_images', Base.metadata,
Column('collection_id', ForeignKey('collections.id'), primary_key=True),
Column('image_id', ForeignKey('images.id'), primary_key=True))
My problem is the following:
1.
Out of the 3 examples below, only one triggers an integrity exception,
the other two does not.
Why?
In all three I'm trying to write to this primary key, which is
referenced, thus should produce an exception. Yet, in 2. and 3. it seem
nothing is happening when collection.id = is set. When I debug via SQL
queries it shows absolutely nothing called for the collection.id = line.
2.
How can I solve this problem? I mean how can I change a primary key's
value which is also used in a multi-to-multi relation?
The DB is PostgreSQL 9.5 with psycopg2.
The examples are:
A. triggers exception:
with transaction.manager:
collections = dbsession.query(Collection).all()
for collection in collections:
image_ids = [i.id for i in collection.images.all()]
image_ids_string = ','.join(sorted(image_ids)) + collection.name
collection.id = md5(image_ids_string)[:16]
B. does not trigger exception
collections = dbsession.query(Collection).all()# ^ and v only these two lines
are swapped with transaction.manager:
for collection in collections:
image_ids = [i.id for i in collection.images.all()]
image_ids_string = ','.join(sorted(image_ids)) + collection.name
collection.id = md5(image_ids_string)[:16]
C. also does not trigger exception
collections = dbsession.query(Collection).all()
for collection in collections:
image_ids = [i.id for i in collection.images.all()]
image_ids_string = ','.join(sorted(image_ids)) + collection.name
with transaction.manager:
collection.id = md5(image_ids_string)[:16]
The exception for the first one is:
sqlalchemy.exc.IntegrityError: (psycopg2.IntegrityError) update or delete
on table "collections" violates foreign key constraint
"fk_collections_images_collection_id_collections" on table
"collections_images" DETAIL: Key (id)=(jC3sN8952urTGrqz) is still
referenced from table "collections_images".
I've also tried onupdate='CASCADE' for both columns in collections_images
but didn't change anything.
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
http://www.sqlalchemy.org/
To post example code, please provide an MCVE: Minimal, Complete, and Verifiable
Example. See http://stackoverflow.com/help/mcve for a full description.
---
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.