SQL Alchemy, how to insert data into two tables and reference foreign key?

点点圈 提交于 2021-02-08 07:34:21

问题


I am inserting a list of python dictionaries into a Postgres database using SQL Alchemy (via Flask_sqlalchemy).

One of the tables is a list of all unique items (table 1), while the second is a time series of data related to an item (table2).

In essence, I want to insert any new row (with unique hash) in to table 1, then insert it's data to table 2. If it already exists in table 1, just insert the "child" in table 2 referencing the entry in table 1.

This is one item in the list, the list has a few hundred of these.

{'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'}

I would like to insert 5662448s608653114 into table1, and then insert all the other data into table2, where i reference the item not by 5662448s608653114, but by it's id in table 1

So I'd get:

Table 1:

____________________
1| 5662448s608653114
2| 5520103

Table 2:

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

I tested this, which does not work:

    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()

The above code inserts the data, but with none instead of the id from the Table 1. It also doesn't seem very efficient, you know that feeling when something can definitely be done a better way ...

Here's the model classes for reference:

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)

Thanks in advance.

Edit: This works, but it doesn't seem very good due to a new session for every item in the loop :/

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:


Your Placement instance won't have an id until it is committed. This is where the tracker_data relationship can help you...

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()

Notice that pl.placement_id is not set to anything. Instead pl is appended to ts.tracker_data and everything should be looked after for you when you call commit.



来源:https://stackoverflow.com/questions/50026672/sql-alchemy-how-to-insert-data-into-two-tables-and-reference-foreign-key

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!