[sqlalchemy] Delete fails using automap with joined inheritance

2014-03-27 Thread Adrian Robert
I have been using the automap extension with postgres, with an inheritance 
structure using the joined inheritance pattern. I could not figure out a 
way to have this reflected from the DB so I define the classes for this 
part of my schema explicitly, and when automap initializes, these classes 
get used (and modified) for those tables and the rest get autogenerated.

It works fine until I try to delete an instance of an inheriting class: 
then I get a circular dependency error which seems to relate to 
relationships and backreferences created for the foreign key relationship 
underlying the joined inheritance.

The attached code demonstrates the issue.  The first run generates the DB 
schema from the classes, and works, any number of times.  On the second 
run, switch the two comments for Base (in two places) to use automap.  The 
output of the first:

% ./test.py
RELATIONSHIPS: []
Run completed successfully.

% ./test.py
RELATIONSHIPS: [('employee', RelationshipProperty at 0x10263d310; 
employee), ('engineer_collection', RelationshipProperty at 0x102663210; 
engineer_collection)]
Circular dependency detected. Cycles: {DeleteState(Engineer at 
0x1026a9d10)} all edges: {(DeleteState(Engineer at 0x1026a9d10), 
DeleteState(Engineer at 0x1026a9d10)), 
(ProcessState(OneToManyDP(Employee.engineer_collection), Engineer at 
0x1026a9d10, delete=True), DeleteState(Engineer at 0x1026a9d10))}

Notice that the mapper in the first case shows no relationships, despite 
the foreign key created for the inheritance.  On the other hand when the 
same structure is read from the DB by automap, we see forward and back 
relationships, which I guess is somehow causing the circular dependency.

Am I doing something wrong in my attempt to use joined inheritance in 
conjunction with automap, or is this a bug or something unsupported?

-- 
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.
#!/usr/bin/env python

from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.schema import ForeignKey

# SWITCH commenting here and below to test
Base = declarative_base()# Run 1
#Base = automap_base(declarative_base=declarative_base())# Run 2

class Employee(Base):
__tablename__ = 'employee'
id = Column(Integer, primary_key=True)
name = Column(String(50))
type = Column(String(50))
__mapper_args__ = {
'polymorphic_identity':'employee', 'polymorphic_on':type
}

class Engineer(Employee):
__tablename__ = 'engineer'
id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
engineer_name = Column(String(30))
__mapper_args__ = {
'polymorphic_identity':'engineer',
}

engine = create_engine(postgresql://user:pw@localhost/test)
Session = sessionmaker(bind=engine)

# SWITCH commenting to test
Base.metadata.create_all(engine)# Run 1
#Base.prepare(engine, reflect=True)# Run 2

# Test
session = Session()
engineer = Engineer(engineer_name='Eng 1', name='Emp 1')
print(RELATIONSHIPS:  + str(engineer.__mapper__.relationships.items()))
session.add(engineer)
session.commit()

session = Session()
engineer = session.query(Engineer).all()[0]
session.delete(engineer)

try:
session.commit()
print(Run completed successfully)
except Exception as e:
print(EXCEPTION:  + str(e))


Re: [sqlalchemy] Automap and naming of relationship attributes

2014-02-06 Thread Adrian Robert
Well, using the mapper event would be nicer, but in any case I was already 
iterating over Base.classes and adding them to my own module's namespace like 
so:

globals()[cls.__name__] = cls

It works for the rest of my application being able to see the classes by 
importing the module, but apparently not for this.  I'm not really expert at 
Python class and namespace innards, but from the error message as well as the 
default str() output it seems the automap-generated classes considers 
themselves to be in the sqlalchemy.ext.automap module but are not registered in 
that namespace.

Is there a way to tell the classes to use a different namespace from an 
instrument_class handler?  (And incidentally I'm already using my own base 
class through automap_base(declarative_base(cls=...)) but that doesn't make any 
difference.)




On 2014.2.6, at 15:59, Michael Bayer mike...@zzzcomputing.com wrote:

 Python pickle can't pickle class instances where the class isn't locatable as 
 module-level imports.  As automap necessarily creates classes on the fly, 
 these classes aren't part of any module.  to have them part of a module you'd 
 want to use an event to place them in the namespace of one of your own 
 modules, or you can implement a custom `__reduce__()` method on them (see the 
 Python docs for __reduce__()).
 
 a good event to use here might be instrument_class:
 
 http://docs.sqlalchemy.org/en/rel_0_9/orm/events.html#sqlalchemy.orm.events.MapperEvents.instrument_class
 
 
 
 On Feb 6, 2014, at 4:32 AM, Adrian Robert adrian.b.rob...@gmail.com wrote:
 
 One other point, I was trying out the dogpile cache example and ran into 
 (after I stuck a .encode('utf-8') into the key mangler since I'm using 
 Python-3 and pylibmc):
 
 _pickle.PicklingError: Can't pickle class 'sqlalchemy.ext.automap.Person': 
 attribute lookup sqlalchemy.ext.automap.Person failed
 
 This was fixed by a hack
 
   sqlalchemy.ext.automap.__dict__[cls.__name__] = cls
 
 run over all the automap-created classes.  It might be I'm only having to do 
 this because I'm doing something wrong elsewhere, but I just thought I'd 
 mention it in case it comes up for someone.
 
 
 
 On 2014.2.2, at 14:22, Adrian Robert adrian.b.rob...@gmail.com wrote:
 
 Thanks, that works beautifully.
 
 I had noticed name_for_scalar_relationship parameter but I guess wasn't 
 confident enough that I understood what was going on to try it.  :-[
 
 
 -- 
 You received this message because you are subscribed to a topic in the 
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit 
 https://groups.google.com/d/topic/sqlalchemy/p6YkPuCs_Ks/unsubscribe.
 To unsubscribe from this group and all its topics, 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.
 
 -- 
 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.
 

-- 
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.


Re: [sqlalchemy] Automap and naming of relationship attributes

2014-02-02 Thread Adrian Robert
Thanks, that works beautifully.

I had noticed name_for_scalar_relationship parameter but I guess wasn't 
confident enough that I understood what was going on to try it.  :-[

-- 
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.