I think your situation is described here:

https://docs.sqlalchemy.org/en/14/orm/session_state_management.html#merge-tips

I'm not certain, but my guess is that when you create westGate, you
cause a *copy* of typeDict['gate'] to be merged into the current
session (because the merge cascades across the objectType
relationship). This instance is marked as pending. Then when you try
to create eastGate, the same thing happens again, but now there is
*already* a pending copy of typeDict['gate'] in the session, so you
get an error.

The easiest solution would be to create a session-specific copy of
typeDict, either by re-querying from the database, or by using
session.merge with load=False.

Hope that helps,

Simon

On Thu, Nov 19, 2020 at 11:16 PM Vinit Shah <[email protected]> wrote:
>
> I posted this on StackOverflow a few days ago, but I haven't been able to 
> figure this one out yet. The original post can be found here: StackOverflow: 
> object "is already present in this session".
>
> I'm seeing the below error:
> sqlalchemy.exc.InvalidRequestError: Can't attach instance <ObjectType at 
> 0x10592fe50>; another instance with key ( <class '__main__.ObjectType'>, 
> (1,), None) is already present in this session.
>
> I'm seeing this issue when I try to instantiate a new object that has a 
> foreign key relationship with an existing object that was created in another 
> session.
>
> This happens in a few different cases in my actual code, but in the provided 
> sample it occurs with the following steps:
> 1. Add a new object into a new session
> 2. Close session and remove() from scoped_session
> 3. Reference the object in two newly constructed ones via their relationship
> 4. Error appears on the second object
>
>     # typeDict just contains a pre-fetched ObjectTypes
>     tokyo = Location(name="tokyo", objectType=typeDict['location'])
>     tokyo = write(tokyo)
>
>     # If I clear out the current session here, the error will occur
>     scopedSessionFactory().close()
>     scopedSessionFactory.remove()
>
>     westGate = Gate(name="westGate", destination=tokyo, 
> objectType=typeDict['gate'])
>     westGate = write(westGate)
>
>     luggage = LocationInput(name="luggage", 
> objectType=typeDict['locationinput'])
>     luggage = write(luggage)
>
>     # This is the line where the error occurs
>     eastGate = Gate(name="eastGate", origin=tokyo, destinationInput=luggage, 
> objectType=typeDict['gate'])
>     eastGate = write(eastGate)
>
> I'm not sure what exactly causes this or way. For this example, I could just 
> reuse the same session, but I'd like to be able to take an object from one 
> closed session and add as a relationship field to another.
>
> Full code sample available here:
> https://gist.github.com/funseiki/a73424bebfb0d809e6d934f699a725bf
>
> --
> 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 view this discussion on the web visit 
> https://groups.google.com/d/msgid/sqlalchemy/4d01df93-16ed-45a4-82f3-de04a8e57bcbn%40googlegroups.com.

-- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/CAFHwexfk-xGOf5Je8Jubq0gtA6U6fFnwnBPj5SOFyArwJ51KbA%40mail.gmail.com.

Reply via email to