Hello all, I'm using `session.merge()` within an HTTP handler, I would like to know which objects have been newly added and which ones have been modified after `merge()` completes.
Bare with me please ... I know there are `before_flush`, etc. events exactly for this scenario but I **only** need to know within the context of my HTTP request handler. I am already using whole application-server `before_flush`, `before_commit`, etc for other purposes. *Here is my use-case scenario:* Consider an object graph that represents folder with sub-folders and files (of any depth). For example: ``` / # root folder /folder1/file1 # file1 within folder1; folder1 within root /folder1/folder2/file2 # file2 within folder2; folder2 within folder1; folder1 within root ``` My sqlalchemy model looks like this: ``` class Folder(Base): ... id = Column(... primary key) folder_id = Column(... foreign key to parent folder id) folder = relationship(... class File(Base): ... id = Column(... primary key) folder_id = Column(... foreign key to parent folder id) folder = relationship(... ``` The HTTP client would like to do a **single** POST containing the new directory structure with folders and subfolders rearranged containing any combination of existing files, existing folders, and to-be created new folders and subfolders. All in a single HTTP POST. *My current solution is like this:* Within my HTTP request handler, the POST payload is validated and newly detached sqlalchemy instances are created (I'm using pyramid, cornice and marshmallow). I use `session.merge()` to automatically "create" and/or "update" my object graph in one shot. Even if this payload object graph contains any combination of persisted objects and new objects. For instance, HTTP client wants the following changes ... /folder3/folder4/folder1/file1 /folder3/folder4/folder1/folder2/file2 ... to be applied over ... /folder1/file1 /folder1/folder2/file2 IOW: client wants to create a new folder3 (containing a new subfolder folder4); putting folder3 in root; and moving folder1 into folder4 - all in one shot: In code, something like this would be happening within marshmallow: ``` folder3 = Folder() folder4 = Folder() folder3.append(folder4) folder4.folders.append(folder1) ``` In my HTTP handler, I'm doing this: ``` folder3 = request.validated['folder'] session.merge(folder3) ``` All this works just fine :) New folders are created and existing folders and existing files are shuffled around correctly. *However*, after the `merge()`, folder3 and folder4 appear in `session.dirty` while `session.new` is empty. Also folder1 appears in `session.dirty`. I.e. `session.dirty` has both newly inserted and modified instances. I need to know that folder3 and folder4 were newly added so I can tell the client "newly added folders: folder3, folder4" - client doesn't care about "updated" folders and/or files, just cares about new folders. So, looking at `session.new` and `session.dirty` doesn't help me identifying which objects were newly inserted and which ones were updated. *How can I know if folder3 was newly added (or any descendant) without having to query the DB for every object in the POSTed object graph before passing all down to `session.merge()`?* I was considering that I could `@event.listens_for('init'...)` within the context of the HTTP request (perhaps `before_flush`) but there is a "dragon warning" (https://docs.sqlalchemy.org/en/latest/core/event.html) about adding/removing events in "high velocity" which sounds like I would be doing here? *Any suggestions?* Perhaps I'm doing this all wrong to start with ... As my last resort, I could just simplify my API and incrementally build the directory structure step by step like a normal "filesystem": folder1 = mkdir('folder1', root) put_file(file1, folder1) folder2 mkdir('folder2', folder1) put_file(file2, folder1) The disadvantage would be that client would need to sequentially send each HTTP request one by one in the correct order. Which is the opposite of the desired use-case scenario. -- 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 sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.