Re: [sqlalchemy] Custom Flush

2015-06-15 Thread Richard Collins
Thanks Michael.

before_flush looks like the way to go. From what I can see so far, it will 
alleviate the need to call my add_or_remove function, increasing 
reliability. 

On Monday, 15 June 2015 10:27:06 UTC+12, Michael Bayer wrote:

  

 On 6/14/15 5:49 PM, Richard Collins wrote:
  
 I have an association object: 

  class FolderUserAccess(db.Model):
 __tablename__ = folderuseraccess
 folder_id = db.Column(db.Integer, db.ForeignKey('node.id'), 
 primary_key=True)
 folder = db.relationship('Folder', back_populates='access')
 user_id = db.Column(db.Integer, db.ForeignKey('user.id'), 
 primary_key=True, index=True)
 user = db.relationship('User')
 access = db.Column(TINYINT, nullable=False)
 walk = db.Column(db.Boolean, nullable=False)
  
  When the object is persisted to the database, I would like to delete the 
 corresponding row when access==0 and walk = False.

  Here is my attempt to make this happen:

  def add_or_remove(self):
 Add or remove object depending on access and walk values 
 ensuring no empty records are stored in database

  if self.access or self.walk:
 if self in db.session.deleted:
 db.make_transient(self)
 else:
 db.session.add(self)
  else:
 if inspect(self).persistent:
 db.session.delete(self)
  
  I call this on the object after updating it. It is complicated as it has 
 to deal with the fact that somewhere else in the same transaction the 
 object may have already been updated. It does not work (I will figure it 
 out eventually) and strikes me as the complicated way of doing things.
  
  What I would really like to do is be able to write a custom 
 implementation for when the object gets flushed. Something like:

if self.access or self.walk:
  #insert or update the row
   else:
  # delete the row

  Is this possible? Or does anyone have any great ideas on how to achieve 
 the same result in a more straightforward way than my current approach.
  
 event hooks like before_flush() or after_flush() are the best place to do 
 things like this.   In before_flush(), you can scan through the list of 
 work to do and add new things to the Session for add() or delete(); in 
 after_flush(), you can look at what's happened and then emit specific SQL 
 on the session.connection() to make other changes after the fact.Other 
 popular hooks include the mapper hooks before_insert(), before_update(), 
 before_delete(), with these it's best to emit SQL on the given connection 
 as things happen within the flush process.




  
  Thanks,

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


  

-- 
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/d/optout.


Re: [sqlalchemy] Custom Flush

2015-06-14 Thread Mike Bayer



On 6/14/15 5:49 PM, Richard Collins wrote:

I have an association object:

class FolderUserAccess(db.Model):
__tablename__ = folderuseraccess
folder_id = db.Column(db.Integer, db.ForeignKey('node.id'), 
primary_key=True)

folder = db.relationship('Folder', back_populates='access')
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), 
primary_key=True, index=True)

user = db.relationship('User')
access = db.Column(TINYINT, nullable=False)
walk = db.Column(db.Boolean, nullable=False)

When the object is persisted to the database, I would like to delete 
the corresponding row when access==0 and walk = False.


Here is my attempt to make this happen:

def add_or_remove(self):
Add or remove object depending on access and walk values 
ensuring no empty records are stored in database


if self.access or self.walk:
if self in db.session.deleted:
db.make_transient(self)
else:
db.session.add(self)
else:
if inspect(self).persistent:
db.session.delete(self)

I call this on the object after updating it. It is complicated as it 
has to deal with the fact that somewhere else in the same transaction 
the object may have already been updated. It does not work (I will 
figure it out eventually) and strikes me as the complicated way of 
doing things.


What I would really like to do is be able to write a custom 
implementation for when the object gets flushed. Something like:


  if self.access or self.walk:
 #insert or update the row
  else:
 # delete the row

Is this possible? Or does anyone have any great ideas on how to 
achieve the same result in a more straightforward way than my current 
approach.
event hooks like before_flush() or after_flush() are the best place to 
do things like this.   In before_flush(), you can scan through the list 
of work to do and add new things to the Session for add() or delete(); 
in after_flush(), you can look at what's happened and then emit specific 
SQL on the session.connection() to make other changes after the fact.
Other popular hooks include the mapper hooks before_insert(), 
before_update(), before_delete(), with these it's best to emit SQL on 
the given connection as things happen within the flush process.







Thanks,

Richard
--
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 
mailto:sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com 
mailto:sqlalchemy@googlegroups.com.

Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


--
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/d/optout.