Reputation: 393
Article
and Image
have many-to-many relationship and their intermediate table is ArticleImage
. I expect I'll see 1 rows in Article
table, 3 rows in Image
table, and 3 rows in ArticleImage
table. Article
and ArticleImage
part are working as expected, however, there is 0 row in Image
table and the foreigh-key column 'image_id' in ArticleImage
table of that 3 newly-added rows are 'NULL'. What am I missing to persist rows in Image
table correctly?
(there is no error printed)
My code:
db_session = some_function() # get connection to database here
try:
article = Article()
db_session.add(article)
article.name = 'new post #1'
article.author = 'pojan'
article.images.append(Image('img1.jpg'))
article.images.append(Image('img2.jpg'))
article.images.append(Image('img3.jpg'))
db_session.merge(article)
db_session.commit()
print db_session.query(Article).count() # 1
print db_session.query(ArticleImage).count() # 3
print db_session.query(Image).count() # 0 <- error here, images are not added
except Exception as e:
print e
I have also tried the following code, now the Image
would be added to database, but the image_id column in ArticleImage
still remain as NULL:
article = Article()
db_session.add(article)
article.name = 'new post #1'
article.author = 'pojan'
image1 = Image('img1.jpg')
image2 = Image('img2.jpg')
image3 = Image('img3.jpg')
db_session.add(image1)
db_session.add(image2)
db_session.add(image3)
article.images.append(image1)
article.images.append(image2)
article.images.append(image3)
db_session.merge(article)
db_session.commit()
My model:
class Image(EntityClass):
attributes = ['id', 'name', 'path']
id = Column(Integer, primary_key=True)
name = Column(String(255), nullable=False)
path = Column(String(255), nullable=False, unique=True)
def __init__(self, name):
self.name = name
self.path = '/root/' + name
class ArticleImage(EntityClass):
article_id = Column(Integer, ForeignKey('article.id'))
image_id = Column(Integer, ForeignKey('image.id'))
image = relationship(Image)
position = Column(Integer)
class Article(EntityClass):
attributes = ['id','name','author']
id = Column(Integer, primary_key=True)
_images = relationship(ArticleImage,
order_by=[ArticleImage.position],
collection_class=ordering_list('position'))
images = association_proxy('_images', 'image')
name = Column(String(255), nullable=False)
author = Column(String(255), nullable=False)
(the design is base on an article I found on internet, and I made some minor changes)
Upvotes: 1
Views: 71
Reputation: 6148
According to the article you refer to, you should also add a constructor in ArticleImage
to associate ArticleImage
with Image
when an ArticleImage
oject is created, otherwise ArticleImage
would never know which image row it should refer to.
class ArticleImage(EntityClass):
article_id = Column(Integer, ForeignKey('article.id'))
image_id = Column(Integer, ForeignKey('image.id'))
image = relationship(Image)
position = Column(Integer)
def __init__(self, image=None):
self.image = image
Upvotes: 1
Reputation: 71
You missed primary key in ArticleImage
compared to the example you give.
I would get
sqlalchemy.exc.ArgumentError: Mapper Mapper|ArticleImage|article_image could not assemble any primary key columns for mapped table 'article_image'
with your ArticleImage
code.
Upvotes: 0