質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
INSERT

INSERTとは、行を追加する、コンピュータのデータベース言語SQLにおけるデータ操作言語(DML)ステートメントの1つである

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

ORM

ORM(オブジェクト関係マッピング)はオブジェクト指向のシステムとリレーショナルデータベースの間でマッピングを行う技術です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

SQLAlchemy

SQLAlchemyとはPython 用のORMライブラリです。MIT Licenceのオープンソースとして提供されています。

Q&A

解決済

2回答

4075閲覧

【Python3】SQLAlchemyを使用し、UpdateとInsertを(1トランザクションで)行いたい

s_akira

総合スコア15

INSERT

INSERTとは、行を追加する、コンピュータのデータベース言語SQLにおけるデータ操作言語(DML)ステートメントの1つである

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

ORM

ORM(オブジェクト関係マッピング)はオブジェクト指向のシステムとリレーショナルデータベースの間でマッピングを行う技術です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

SQLAlchemy

SQLAlchemyとはPython 用のORMライブラリです。MIT Licenceのオープンソースとして提供されています。

0グッド

0クリップ

投稿2019/08/28 06:43

編集2019/09/10 09:04

実現したいこと

SQLAlchemyを使用して、UpdateとInsertを1トランザクションで行いたいです。

詳細:
入力画面上で、"ID"と"str"が入力出来る画面があります。
"ID"が登録あった場合、入力[ID]の"end"を現在時刻に更新、更新した"ID"と入力された"str"を登録(insert)したいです。
※もはや、何をどうしたらいいのかわからなくなりました。insertとupdateがよくわかっていないのかもしれません・・・すみません。

実現したいDB

(もともとのDB(con)の状態)
|id|str|start      |   end
|:--|:--:|--:|
|1|aaa|2019-08-22 23:27:13|9999-12-31 09:00:00

上記DBが、下記のように更新されるイメージ。(↓)
teime_endを現在日時に更新して、同じidで登録する。(strが入力画面から受け取った内容)
|id|str|start | end        
|:--|:--:|--:|
|1|aaa|2019-08-26 23:27:13|2019-08-28 23:27:13(現在日時に更新(now()))
|1|bbb|2019-08-26 23:27:13|9999-12-31 09:00:00(☆ここが追加(insert))

※プライマリーキーのことは、忘れてください。

現状

下に、途中コードを載せますがここから先どうしたらいいのかで止まっています。
現在"name 'm_data' is not defined"エラーで止まっている状態です。
(自身で解決できれば、すぐにコードを更新致します。申し訳ありません。)

作成中のコード

b.py

python

1class Con: 2  def put_main(self, id): 3 # Update 4 update = Con.query.filter(id == id).first() 5 update.end = datetime.datetime.now() 6 if update is None: 7 print('NotUpdate') 8 else: 9      # updateaあったらinsert 10 data = [] 11 # insert 12 insert = Con( 13 id = data['id'], 14 str = data['str'], 15 start= created_time, 16 end = datetime.date.max, 17 ) 18 m_set.append(insert) 19 contact = Contact(**data) 20 m_set.append(contact) 21 self.__commit(update, insert) 22 return m_set 23

現在以下のURL参考に進めています。

SQLAlchemyでUpdateするには
SQLAlchemyの基本的な使い方
SQLAlchemyで基本的なSQLクエリまとめ
など...

こんな感じでやれば出来るのではないかなどのアドバイスだけでも頂ければ幸いです。
updateとinsertしたいです・・・よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

混乱して意味がわからなくなり困ったので、updateとinsert分けました。
1トランザクションでの話は、再度調査し直しいたします。
このような形になり、申し訳ないです。。

Python

1 def update(self, update_data): 2 update_data.valid_time_end = datetime.datetime.now() 3 self.__commit(update_data) 4 5 def insert(self, id, date): 6 # insert 7 insert = Table( 8 id = data['id'], 9 str = data['str'], 10 start= created_time, 11 end = datetime.date.max, 12 ) 13 self.__commit(insert)

投稿2019/09/10 09:12

s_akira

総合スコア15

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

今ひとつやりたいことがわからないのですが、Sessionを使ってトランザクション管理をするだけでは駄目なのでしょうか??

Python

1from sqlalchemy import create_engine 2from sqlalchemy import extract 3from sqlalchemy import Column, Integer, String, DATETIME 4from sqlalchemy.ext.declarative import declarative_base 5from sqlalchemy.orm import sessionmaker 6from datetime import datetime 7import time 8 9engine = create_engine('sqlite:///:memory:', echo=True) 10base = declarative_base() 11 12class Con(base): 13 14 def __init__(self, name): 15 self.str = name 16 self.start = datetime.now() 17 self.end = datetime.now() 18 19 __tablename__ = 'con' 20 21 id = Column(Integer(), 22 nullable=False, 23 primary_key=True, 24 autoincrement=True, 25 unique=True, 26 comment="ID") 27 str = Column(String(128), nullable=False) 28 start = Column(DATETIME, nullable=False) 29 end = Column(DATETIME, nullable=False) 30 31base.metadata.create_all(engine) 32 33Session = sessionmaker(bind=engine) 34session = Session() 35 36# とりあえず最初の状態を作る 37session.add(Con('aaa')) 38session.add(Con('bbb')) 39session.commit() 40 41time.sleep(3) 42 43# ここから以下を1トランザクションで行いたい 44print("-----") 45session.add(Con('ccc')) # データを追加 46session.query(Con).update({'end':datetime.now()}) # 全データの'end'を更新 47session.commit() 48print("-----") 49 50# 一応結果表示 51for c in session.query(Con).all(): 52 print(f'{c.id}, {c.str}, {c.start} {c.end}')

投稿2019/08/28 08:24

magichan

総合スコア15898

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

s_akira

2019/08/28 08:43

言葉足らず、わかりずらく申し訳ありません。 "既存データ更新"と"更新されたidと画面入力値のinsert"をしたいだけなのです…うまく言えなくて申し訳ありません。 自身も混乱しているため、今一度質問を読み直しと修正行いたいと思います。 トランザクション管理のコードを貼ってくださりありがとうございます。 参考にさせていただきます。ご回答ありがとうございます。
magichan

2019/08/28 08:50

私のサンプルコードにて、質問の「実現したいDB」 をほぼ実現できてると思うのですが、まだなにか足りないでしょうか?
s_akira

2019/09/10 09:16

サンプルコードを参考にしようと思ったのですが、うまく動作ができませんでした。 また、理解がおよびませんでした・・・申し訳ありません。 改め、勉強し直します。 ご回答いただいたのに、私の理解が及ばず大変申し訳ありません。 ご回答頂きありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問