I am basing my question off the code
at
http://docs.sqlalchemy.org/en/latest/orm/relationship_persistence.html#rows-that-point-to-themselves-mutually-dependent-rows,
with a few changes.
I am trying to handle a situation very similar to the one in that example,
with 2 classes having the same relationship types as those in the example.
However, I would like to create the instances without using the
relationships, and instead populate the fk values directly. The example
uses this, and it works.
w1 = Widget(name='somewidget')
e1 = Entry(name='someentry')
w1.favorite_entry = e1
w1.entries = [e1]
session.add_all([w1, e1])
session.commit()
I would like to do this:
w1 = Widget(widget_id=1, favorite_entry_id=1, name='somewidget')
e1 = Entry(entry_id=1, widget_id=1, name='someentry')
session.add_all([w1, e1])
session.commit()
The reason I am doing it this way is because I am operating from a JSON
fixture file, and trying to populate a database for unit testing. The
method used in the example works perfectly, but trying to do it my way
yields:
sqlalchemy.exc.IntegrityError: (IntegrityError) (1452, 'Cannot add or
update a child row: a foreign key constraint fails (`test`.`widget`,
CONSTRAINT `fk_favorite_entry` FOREIGN KEY (`favorite_entry_id`) REFERENCES
`entry` (`entry_id`))') 'INSERT INTO widget (widget_id, favorite_entry_id,
name) VALUES (%s, %s, %s)' (1, 1, 'somewidget')
I understand the post_update option is on the relationship, and not the
column, so it has no effect on column population. Is there an alternative
method to have that column populated separately via a second statement,
similar to the post_update functionality?
--
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 post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.
from sqlalchemy import Integer, ForeignKey, Column, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy.orm.session import Session
dsn = 'mysql://scott:tiger@localhost/test'
engine = create_engine(dsn)
Base = declarative_base(bind=engine)
class Entry(Base):
__tablename__ = 'entry'
entry_id = Column(Integer, primary_key=True)
widget_id = Column(Integer, ForeignKey('widget.widget_id'))
name = Column(String(50))
class Widget(Base):
__tablename__ = 'widget'
widget_id = Column(Integer, primary_key=True)
favorite_entry_id = Column(Integer,
ForeignKey('entry.entry_id',
name="fk_favorite_entry",
use_alter=True))
name = Column(String(50))
entries = relationship(Entry, primaryjoin=
widget_id==Entry.widget_id)
favorite_entry = relationship(Entry,
primaryjoin=
favorite_entry_id==Entry.entry_id,
post_update=True)
Base.metadata.drop_all()
Base.metadata.create_all()
session = Session(bind=engine)
# this works
w1 = Widget(name='somewidget')
e1 = Entry(name='someentry')
w1.favorite_entry = e1
w1.entries = [e1]
session.add_all([w1, e1])
session.commit()
# this doesn't
'''
w1 = Widget(widget_id=1, favorite_entry_id=1, name='somewidget')
e1 = Entry(entry_id=1, widget_id=1, name='someentry')
session.add_all([w1, e1])
session.commit()
'''