On 07/29/2016 06:39 PM, Eric Wittle wrote:
> I don't have sqlite installed, so I skipped actually creating the engine,
all Python versions have sqlite3 included in the distribution itself
unless you're on Jython (which I doubt works with SQLA these days)?
>
> |
> fromsqlalchemy importColumn,String,Integer,ForeignKey
> fromsqlalchemy.orm importrelationship,backref
> fromsqlalchemy.ext.associationproxy importassociation_proxy
> fromsqlalchemy.ext.declarative importdeclarative_base
>
>
> Base=declarative_base()
>
>
> classPerson(Base):
> __tablename__ ='Person'
> id =Column(Integer,primary_key=True)
> first_name =Column(String(80))
> last_name =Column(String(120))
> events =association_proxy('person_events','Event')
>
>
> classPersonEvent(Base):
> __tablename__ ='PersonEvent';
> person_id =Column(Integer,ForeignKey('Person.id'),primary_key=True)
> event_id =Column(Integer,ForeignKey('Event.id'),primary_key =True)
> role =Column(String(40))
>
>
> # bi-directional attribute / collection of "Person" / "Event"
> person =relationship(Person,
> backref=backref('person_events',
> cascade="all, delete-orphan"))
>
> # reference to the Event object
> event=relationship('Event')
> def__init__(self,person=None,event=None,role=None):
> self.person =person
> self.event=event
> self.role =role
>
>
> classEvent(Base):
> __tablename__ ='Event'
> id =Column(Integer,primary_key=True)
> short_name =Column(String(40))
>
>
> p1 =Person(first_name='Eric',last_name='Wittle')
> p1.events.append(Event(short_name='Birth'))
here's how you debug this. Use pdb:
def __init__(self, person=None, event=None, role=None):
import pdb
pdb.set_trace()
self.person = person
self.event = event
self.role = role
then:
> /home/classic/dev/sqlalchemy/test.py(35)__init__()
-> self.person = person
(Pdb) !person
<__main__.Event object at 0x7ff6180f06d0>
we can see that your PersonEvent has a constructor that is not
compatible with the documented default creator behavior:
http://docs.sqlalchemy.org/en/rel_1_0/orm/extensions/associationproxy.html#creation-of-new-values
now the "creator" thing in association_proxy is not very good or
intuitive, but we are stuck with it for now. So pass in a real creator:
class Person(Base):
__tablename__ = 'Person'
id = Column(Integer, primary_key=True)
first_name = Column(String(80))
last_name = Column(String(120))
events = association_proxy('person_events','Event',
creator=lambda event: PersonEvent(event=event))
> |
>
> I thought I was fairly faithfully following the example in Simplifying
> Association Proxies. I'm assuming the first argument to assocation_proxy
> is the name of the backref created in the relationship in the
> association object, but I'm unclear on that. I tried your code
> suggestion (minus actually creating the engine and adding in the
> __init__ method to the association object to work around __init__ takes
> 1 positional argument but two were given error). The edited version I
> ran is below, and it also gives KeyError:
>
> |
> fromsqlalchemy import*
> fromsqlalchemy.orm import*
> fromsqlalchemy.ext.declarative importdeclarative_base
> importdatetime
> fromsqlalchemy.ext.associationproxy importassociation_proxy
>
> Base=declarative_base()
>
> classPerson(Base):
> __tablename__ ='Person'
> __table_args__ ={'mysql_charset':'utf8'}
> id =Column(Integer,primary_key=True)
> full_name =Column(String(240))
> email =Column(String(120),unique=True)
> other_data =Column(String(50))
> events =association_proxy('PersonEvent','Event')
>
> classPersonEvent(Base):
> __tablename__ ='PersonEvent'
> __tableargs__ ={'mysql_charset':'utf8'}
> person_id =Column(Integer,ForeignKey('Person.id'),primary_key=True)
> event_id =Column(Integer,ForeignKey('Event.id'),primary_key =True)
> role =Column(String(40))
>
> # bi-directional attribute / collection of "Person" / "Event"
> person =relationship('Person',
> backref=backref("PersonEvent",
> cascade="all, delete-orphan"))
>
> # reference to the Event object
> event=relationship('Event')
>
> def__init__(self,person=None,event=None,role=None):
> self.person =person
> self.event=event
> self.role =role
>
> classEvent(Base):
> __tablename__ ='Event'
> __table_args__ ={'mysql_charset':'utf8'}
> id =Column(Integer,primary_key=True)
> short_name =Column(String(40))
> name =Column(String(240))
> other_data =Column(String(100))
>
> p1 =Person(id=1,full_name='Eric L. Wittle',email='
er...@wittle.net')
> e1 =Event(id=1,name='Birth')
> p1.events.append(e1)
> |
>
> This is running python 3.5.1 with SQLAlchemy 1.1.0b2.
>
> -Eric
>
>
>
>
>
>
>
>
>
>
>
>
>
>