1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

sqlalchemyを使ったDBのテーブル挿入処理

Last updated at Posted at 2016-07-15

ex1)複数レコードを任意のテーブルにInsert処理する(その1)

 最初の頃は不本意ながら、愚直?にmyobjectに各列の値をセットしてsession.add(myobject)する処理をforループで繰り返す方法でテーブルに1行ずつレコード挿入しておりましたorz

sql_insert_old.py

Base = sqlalchemy.ext.declarative.declarative_base()

class Hogega_tmp(Base):
    __tablename__ = 'hogega_tmps'
    id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
    y = sqlalchemy.Column(sqlalchemy.String(10))
    m = sqlalchemy.Column(sqlalchemy.String(10))
    d = sqlalchemy.Column(sqlalchemy.String(10))
    dim4 = sqlalchemy.Column(sqlalchemy.String(100))
    pv = sqlalchemy.Column(sqlalchemy.String(50))
    rsf = sqlalchemy.Column(sqlalchemy.String(10))
    fld = sqlalchemy.Column(sqlalchemy.String(10))

def orm(data,fld):
    
    # SQLAlchemyの初期化
    CONNECT_INFO = 'mssql+pyodbc://hogehoge'
    engine = sqlalchemy.create_engine(CONNECT_INFO, encoding='utf-8')

    # セッション作成
    Session = sqlalchemy.orm.sessionmaker(bind=engine)
    session = Session()

    #無作為抽出機能有無
    if data["containsSampledData"]:
       rsf=1
    else:
       rsf=0
    cnt=data["totalResults"]
    print(ref)

    #ループ処理で1件ずつテーブルにレコード挿入
    if cnt!=0: 
       for i,n in enumerate(data["rows"]): 
           print(i)
           if fld.find("source")!= -1: 
               myobject = Hogega_tmp(y=n[0],m=n[1],d=n[2],dim4=n[3],pv=n[4]
                                     rsf=rsf,fld=fld)
       
           session.add(myobject) #行挿入
           if fld.find("source")!= -1 and i>=24: #挿入件数を限定
                  break
       session.commit() #コミット
    session.close() #セッション閉じる

注)上記では例えばGoogle AnalyticsのAPIを実行した結果を、SQL Serverに格納するシーンを想定

ex2)複数レコードを任意のテーブルにInsert処理する(その2)

 1件ずつ行挿入を繰り返すのはやはりイケてないというか、SQLでも複数データを1回のInsert文でまとめて行挿入できるので、それがSqlalchemyで実現できないものか模索したのが以下のスクリプト。

sql_insert_new.py

def orm2(data,fld):
    
    # SQLAlchemyの初期化
    CONNECT_INFO = 'mssql+pyodbc://hogehoge'
    engine = sqlalchemy.create_engine(CONNECT_INFO, encoding='utf-8')

    # セッション作成
    Session = sqlalchemy.orm.sessionmaker(bind=engine)
    session = Session()

    #無作為抽出機能有無
    if data["containsSampledData"]:
       rsf=1
    else:
       rsf=0


    clm =["y","m","d","dim4","pv","rsf","fld"]
    ex=[rsf,fld]
    cnt=data["totalResults"]

    if cnt!=0: 
       rws = data["rows"]   
       if fld.find("source")!= -1: 
          rws = rws[:25] #挿入件数を限定

       #行挿入
       lst = [dict(zip(clm,r+ex)) for r in rws ] #value句生成
       ins_statement = Hogega_tmp.__table__.insert().values(lst)
       session.execute(ins_statement)   
       session.commit()
       session.close()

補足

 Insert文を引数(lst)の部分に、以下のような「複数の辞書を内包しているリスト」を記述すれば、forループで1件ずつ挿入処理を繰り返ししなくても、複数データを一括でテーブル行挿入ができる模様。(つまりSQLの「Insert Into ... Values ...」のValues句の部分に相当)

sql_insert_apdx1.py
[{y:2016,m:5,d:1,dim4:yahoo,pv:100},
 {y:2016,m:5,d:1,dim4:google,pv:200},
    ...
 {y:2016,m:5,d:1,dim4:smartnews,pv:300}]

 なお上記のsql_insert_new.pyではリスト内包表記のlstは、処理の意味をかみ砕くと以下のようなイメージになる。

sql_insert_apdx2.py
lst = list()
for r in rws:
    vle = r+ex
    y = dict(zip(clm,vle)
    lst.append(y)

(vleがテーブルに格納する値、clmがテーブル列名に相当し、それら2つのシーケンシャルをZIP()でリスト化して辞書型yにしたものを、リストlstに順次追記する処理をforループで繰り返す的な意味合い)

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?