flaskでwebアプリ制作しながらプログラミングの勉強をしています
現在持っているデータをどのようにdbに登録すればいいのか、お教えください。
使用
- Flask-SQLAlchemy
- sqllite3
持っているデータ
title | act | maker |
---|---|---|
タイタニック | ディカプリオ | 20世紀fox |
タイタニック | ケイト・ウィンスレット | 20世紀fox |
アイアンマン | Robert John Downey Jr. | パラマウント |
アイアンマン | グウィネス・パルトロー | パラマウント |
アイアンマン3 | Robert John Downey Jr. | ディズニー |
アベンジャーズ | Robert John Downey Jr. | ディズニー |
想定したdbの設定
- titleーact ; many to many → 中間テーブル(appearance)
- title-maker ; one to many
flaskSQLAlchemyのドキュメントを参考に
appearance = db.Table('appearance', db.Column('act_id', db.Integer, db.ForeignKey('act.id'), primary_key=True), db.Column('detail_id', db.Integer, db.ForeignKey('detail.id'), primary_key=True)) class Act(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50),unique=True) class Maker(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50),unique=True) class Detail(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(80), nullable=False,unique=True) act = db.relationship("Act",secondary=appearance) maker_id = db.Column(db.Integer, db.ForeignKey('maker.id')) maker = db.relationship('Maker', backref=db.backref('makers', lazy=True)) d=Detail(title=t, maker=m,act=[a]) db.session.add(s) db.session.commit()
このように設定しました。
次にデータを登録するために
for文で回して登録しようと思い
s=Detail(title=t, maker=m,act=[a]) db.session.add(s)
試してみると重複のため登録できませんでした
色々、調べて2つの方法を試しました。
ユニーク制約を外す
ユニーク制約を外すと重複されて登録されてしまう
→リレーションdbの意味がない?持っているデータとあまり変わらない?
upsertで登録作業をする
def upsert_stmt(): stmt = insert(Detail) return stmt.on_conflict_do_update( index_elements=['id'], set_={ 'title': stmt.excluded.title, 'maker': stmt.excluded.maker, 'act': stmt.act }) db.session.execute(stmt) #エラー IntegrityError: (sqlite3.IntegrityError) NOT NULL constraint failed db.session.add(stmt) #エラー UnmappedInstanceError: Class 'sqlalchemy.dialects.postgresql.dml.Insert' is not mapped
https://qiita.com/nsuhara/items/86570f789093222252b1
def suffix_insert(insert, compiler, **kwargs): stmt = compiler.visit_insert(insert, **kwargs) if insert.dialect_kwargs.get('sqlite_on_conflict_do_nothing'): stmt += ' ON CONFLICT DO NOTHING' return stmt Insert.argument_for('sqlite', 'on_conflict_do_nothing', False) some_random_values = detail stmt = db.insert(Detail, sqlite_on_conflict_do_nothing=True).values(some_random_values) db.session.execute(stmt) #エラー CompileError: Unconsumed column names
https://stackoverflow.com/questions/64900812/how-to-use-sqlites-upsert-or-on-conflict-with-flask-sqlalchemy
→リレーション関係ところの設定がうまくいっていない?
upsertの方法はエラーがでてうまくいきませんでした
質問は
重複をもつデータのリレーションな関係で登録する方法です。
どうすれば、簡単に登録できるのかお願い致します。
(そもそもの方向性があっているのか、もし間違っていたらそのプロセスもお教えください。)
回答1件
あなたの回答
tips
プレビュー