2016-03-08 76 views
1

我已經創建了一個包含項目,以標籤的許多一對多關係的燒瓶SQLAlchemy的API。瓶SQLAlchemy的多對多插入重複條目

一個簡單的添加沒有問題(在適當的表格中插入項目和標籤),但是如果我添加具有相同標籤名稱的另一個項目,它會創建一個重複的標籤名稱集合,而不僅僅是將關聯表格鏈接到現有的標籤條目。

我發現某些情況下是非常接近我要問,但不完全一樣,我真的很努力試圖理解來做到這一點的最好辦法。 (?) -

所以,問題是:在標籤表中只有唯一條目,同時仍然正確地將標籤與商品表關聯的最佳方式是什麼?

謝謝任何​​幫助/指導!

這裏是我的模型:

items_tags = db.Table('items_tags', 
    db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')), 
    db.Column('item_id', db.Integer, db.ForeignKey('item.id')) 
) 

class Item(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    title = db.Column(db.String(80), unique=False) 
    code = db.Column(db.String(), unique=False) 
    notes = db.Column(db.String(), unique=False) 

    tags = db.relationship('Tag', secondary=items_tags, back_populates="items") 

    def json(self): 
     list_tag = [] 
     for tag in self.tags: 
      list_tag.append({"tag": tag.name, "id": tag.id }) 
     return json.loads(json.dumps({"id": self.id, "title": self.title, "code": self.code, "notes": self.notes, "tags" : list_tag })) 

    def __init__(self, title, code, notes, tags): 
     self.title = title 
     self.code = code 
     self.notes = notes   
     self.tags = tags 

    def __repr__(self): 
     return self.title 

class Tag(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(50)) 

    items = db.relationship('Item', secondary=items_tags, back_populates="tags") 

    def json(self): 
     return {'id': self.id, 'tag': self.name} 

    def __init__(self, name): 
     self.name = name 

    def __repr__(self): 
     return self.name 

這裏是控制器:

# curl -k -H "Content-Type: application/json" -X POST https://x.x.x.x/api/v1.0/items/ -d '{"title": "title03", "code": "code03", "notes": "notes03", "tags": [{"tag": "tag01"}, {"tag": "tag02"}]}' 
@app.route('/api/v1.0/items/', methods=['GET', 'POST']) 
def items(): 
    if request.method == 'GET': 
     return jsonify({"items": [item.json() for item in Item.query.all()]}) 

    if request.method == 'POST': 
     if 'tags' in request.json: 
      tags = request.json['tags']  
      for tag in tags: 
       list_tags = [Tag(tag['tag']) for tag in tags] 

     item = Item(request.json['title'], request.json['code'], request.json['notes'], list_tags) 
     db.session.merge(item) 
     db.session.commit() 
     return jsonify({}), 201 
+2

您的理解中創建新的標籤。如果你不想重複你需要改變你如何做,以加載現有的記錄 – dirn

+0

@dirn我想這就是我卡住的地方。 Item對象創建時,我不必提供一個Tag對象列表嗎?如果我更改列表理解以在標記表中查找現有對象,是否不會在關聯表中丟失我的關係? – you

+0

您只會失去未包含在列表中的標籤的關聯。 – dirn

回答

0

我失蹤了,我需要查詢,看是否標籤第一存在的事實,(是什麼@dirn以「改變你如何做到這一點來加載現有記錄」)。

這裏是我做的,使不加確定重複標籤:

if request.method == 'POST': 
    if 'tags' in request.json: 
     list_tags = [] 
     for tag in request.json['tags']: 
      if Tag.query.filter_by(name=tag['tag']).first(): 
       list_tags.append(Tag.query.filter_by(name=tag['tag']).first()) 
      else: 
       list_tags.append(Tag(tag['tag'])) 

    item = Item(request.json['title'], request.json['code'], request.json['notes'], list_tags) 
    db.session.merge(item) 
    db.session.commit() 
    return jsonify({}), 201