Well, users are not expected to run sql query like DELETE FROM directly, but
they have a GUI that allows them to CRUD tags. The GUI is working with data
through sqlalchemy ORM.

Anyway - passive_deletes='all' does the trick. Many thanks!

 

From: sqlalchemy@googlegroups.com [mailto:sqlalchemy@googlegroups.com] On
Behalf Of Michael Bayer
Sent: Sunday, December 08, 2013 1:46 AM
To: sqlalchemy@googlegroups.com
Subject: Re: [sqlalchemy] Many2many, referential integrity and introspection

 

 

On Dec 7, 2013, at 6:18 PM, Alexey Vihorev <viho...@gmail.com> wrote:





In my case, table 'tags' is editable by users, so I want to avoid them
deleting a tag that's in use by any product. 

 

deleting..using a SQL DELETE statement directly?   If you use real foreign
keys then the database will prevent deletion of rows that are referred to by
rows in the many-to-many table.

 

If you're referring ORM relationship code, the "delete the rows in the
secondary table" feature can be disabled using "passive_deletes='all'" - in
which case you'll then get the above mentioned integrity violation generated
from the database.

 

E.g.:

 

class Tag(Base):

    __tablename__ = 'tags'

    id = Column(Integer, primary_key=True)

    name = Column(Unicode(20))

    products = relationship("Product", secondary=product_tags,
passive_deletes="all")

 

class Product(Base):

    __tablename__ = 'products'

    id = Column(Integer, primary_key=True)

    name = Column(Unicode(20))

 

    tags = relationship("Tag", secondary=product_tags,
passive_deletes="all")

 

 

program output is then:

 

sqlalchemy.exc.IntegrityError: (IntegrityError) update or delete on table
"tags" violates foreign key constraint "product_tags_tag_id_fkey" on table
"product_tags"

DETAIL:  Key (id)=(1) is still referenced from table "product_tags".

 'DELETE FROM tags WHERE tags.id = %(id)s' {'id': 1}

 

 

 

 

 

 





As it is now, they can delete the tag and the system just erases all traces
of it from all products.

 

 

From: sqlalchemy@googlegroups.com [mailto:sqlalchemy@googlegroups.com] On
Behalf Of Michael Bayer
Sent: Saturday, December 07, 2013 11:51 PM
To: sqlalchemy@googlegroups.com
Subject: Re: [sqlalchemy] Many2many, referential integrity and introspection

 

 

On Dec 7, 2013, at 2:22 PM, Alexey Vihorev < <mailto:viho...@gmail.com>
viho...@gmail.com> wrote:






Here is the full code:

 

from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy import *

from sqlalchemy.orm import relationship, sessionmaker

 

Base = declarative_base()

 

product_tags = Table(

    'product_tags', Base.metadata,

    Column('product_id', Integer, ForeignKey('products.id')),

    Column('tag_id', Integer, ForeignKey('tags.id'))

    )

 

class Tag(Base):

    __tablename__ = 'tags'

    id = Column(Integer, primary_key=True)

    name = Column(Unicode(20))

    products = relationship("Product", secondary=product_tags)

 

class Product(Base):

    __tablename__ = 'products'

    id = Column(Integer, primary_key=True)

    name = Column(Unicode(20))

 

    tags = relationship("Tag", secondary=product_tags)

 

 

engine = create_engine(' <postgresql://user:password@localhost/example'>
postgresql://user:password@localhost/example')

Session = sessionmaker(bind=engine)

Base.metadata.drop_all(engine)

Base.metadata.create_all(engine)

 

p1 = Product(name = 'Milk')

p2 = Product(name = 'Water')

 

tag1 = Tag(name='Liquid')

 

p1.tags.append(tag1)

p2.tags.append(tag1)

 

s = Session()

s.add_all([p1, p2, tag1])

s.commit()

s.close()

 

s = Session()

s.delete(s.query(Tag).first())

s.commit()

s.close()

 

After it runs, the product_tags table is completely empty.

 

that's the right behavior, if you remove the Tag, then the row in "tags" is
gone.  It would be a referential integrity violation if rows remained in
product_tags.

 

if you want to remove rows from product_tags specifically, just alter the
collections as needed:

 

p1.tags.remove(tag1)

 

this is a common misunderstanding so a documentation section exists for it:

 

 
<http://docs.sqlalchemy.org/en/rel_0_9/orm/relationships.html#deleting-rows-
from-the-many-to-many-table>
http://docs.sqlalchemy.org/en/rel_0_9/orm/relationships.html#deleting-rows-f
rom-the-many-to-many-table

 

 






 

From:  <mailto:sqlalchemy@googlegroups.com> sqlalchemy@googlegroups.com [
<mailto:sqlalchemy@googlegroups.com> mailto:sqlalchemy@googlegroups.com] On
Behalf Of Jonathan Vanasco
Sent: Friday, December 06, 2013 6:07 PM
To:  <mailto:sqlalchemy@googlegroups.com> sqlalchemy@googlegroups.com
Subject: [sqlalchemy] Re: Many2many, referential integrity and introspection

 

can you share your existing schema for these relations ?

-- 
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 <mailto:sqlalchemy+unsubscr...@googlegroups.com>
sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to  <mailto:sqlalchemy@googlegroups.com>
sqlalchemy@googlegroups.com.
Visit this group at  <http://groups.google.com/group/sqlalchemy>
http://groups.google.com/group/sqlalchemy.
For more options, visit  <https://groups.google.com/groups/opt_out>
https://groups.google.com/groups/opt_out.

 

-- 
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 <mailto:sqlalchemy+unsubscr...@googlegroups.com>
sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to  <mailto:sqlalchemy@googlegroups.com>
sqlalchemy@googlegroups.com.
Visit this group at  <http://groups.google.com/group/sqlalchemy>
http://groups.google.com/group/sqlalchemy.
For more options, visit  <https://groups.google.com/groups/opt_out>
https://groups.google.com/groups/opt_out.

 

 

-- 
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 <mailto:sqlalchemy+unsubscr...@googlegroups.com>
sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to  <mailto:sqlalchemy@googlegroups.com>
sqlalchemy@googlegroups.com.
Visit this group at  <http://groups.google.com/group/sqlalchemy>
http://groups.google.com/group/sqlalchemy.
For more options, visit  <https://groups.google.com/groups/opt_out>
https://groups.google.com/groups/opt_out.

 

-- 
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 sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to