SQL Alchemy, как вставить данные в две таблицы и ссылочный внешний ключ? - PullRequest
0 голосов
/ 25 апреля 2018

Я вставляю список словарей Python в базу данных Postgres, используя SQL Alchemy (через Flask_sqlalchemy).

Одна из таблиц представляет собой список всех уникальных элементов (таблица 1), а вторая представляет собой временной ряд данных, связанных с элементом (таблица2).

По сути, я хочу вставить любую новую строку (с уникальным хэшем) в таблицу 1, а затем вставить ее данные в таблицу 2. Если она уже существует в таблице 1, просто вставьте «дочерний элемент» в таблицу 2, ссылаясь на запись в таблице 1.

Это один элемент в списке, в списке их несколько сотен.

{'placement': '5662448s608653114', 't1': datetime.datetime(2018, 4, 15, 17, 47, 7, 434982), 't2': datetime.datetime(2018, 4, 25, 17, 47, 7, 434994), 'camp_id': 1, 'clicks': '0', 'visits': '3', 'conversions': '0', 'revenue': '0'}

Я хотел бы вставить 5662448s608653114 в table1 , а затем вставить все остальные данные в table2 , где я ссылаюсь на элемент не по 5662448s608653114, а по его идентификатору в таблице 1

Итак, я бы получил:

Таблица 1:

____________________
1| 5662448s608653114
2| 5520103

Таблица 2:

ID | Pl id | T1 | T2 | cost | revenue | clicks
_______________________________________________
499| 1     |
500| 2     |

Я проверял это, которое не работает:

    def write_tracker_data(self):

    for item in self.data:
        ts = Placements(placement_ts_hash=item["placement"])
        pl = TrackerPlacementData(placement_id=ts.id, t1=item["t1"], t2=item["t2"], camp_id=1,  revenue=item["revenue"], clicks=item["clicks"], conversions=item["conversions"])
        db.session.add(pl)

    db.session.commit()

Приведенный выше код вставляет данные, но без идентификатора из идентификатора из Таблицы 1. Это также не кажется очень эффективным, вы знаете, такое чувство, когда что-то определенно можно сделать лучше ...

Вот классы моделей для справки:

class Placements(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    traffic_source = db.Column(db.Integer, db.ForeignKey('ts_types.id'))
    placement_ts_hash = db.Column(db.String, index=True)
    placement_url = db.Column(db.String)
    placement_type = db.Column(db.String)

    # Relationship betwwen unique placement table and tracker_placeemnt_data
    tracker_data = db.relationship("TrackerPlacementData", backref="placement_hash")

class TrackerPlacementData(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    t1 = db.Column(db.DateTime(timezone=True))
    t2 = db.Column(db.DateTime(timezone=True), index=True)
    camp_id = db.Column(db.Integer, db.ForeignKey('campaigns.id'), nullable=False)
    placement_id = db.Column(db.Integer, db.ForeignKey('placements.id'), nullable=True, index=True)
    revenue = db.Column(db.Float)
    clicks = db.Column(db.Integer)
    conversions = db.Column(db.Integer)

Заранее спасибо.

Редактировать: работает , но не очень хорошо из-за нового сеанса для каждого элемента в цикле: /

def write_tracker_data (self):

for item in self.data:
    ts = Placements(placement_ts_hash=item["placement"])
    db.session.add(ts)
    db.session.commit()

    pl = TrackerPlacementData(placement_hash=ts, t1=item["t1"], t2=item["t2"], camp_id=1,
                              revenue=item["revenue"], clicks=item["clicks"], conversions=item["conversions"])
    db.session.add(pl)

    db.session.commit()

1 Ответ

0 голосов
/ 27 апреля 2018

У вашего Placement экземпляра не будет идентификатора, пока он не будет зафиксирован. Вот где вам могут помочь отношения tracker_data ...

for item in self.data:
    ts = Placements(placement_ts_hash=item["placement"])
    pl = TrackerPlacementData(
        t1=item["t1"], 
        t2=item["t2"], 
        camp_id=1, 
        revenue=item["revenue"], 
        clicks=item["clicks"], 
        conversions=item["conversions"]
    )
    ts.tracker_data.append(pl)
    db.session.add(ts)
db.session.commit()

Обратите внимание, что pl.placement_id ничего не установлено. Вместо этого pl добавляется к ts.tracker_data, и за вами все должно заботиться, когда вы вызываете commit.

...