ex1)複数レコードを任意のテーブルにInsert処理する(その1)
最初の頃は不本意ながら、愚直?にmyobjectに各列の値をセットしてsession.add(myobject)する処理をforループで繰り返す方法でテーブルに1行ずつレコード挿入しておりましたorz
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で実現できないものか模索したのが以下のスクリプト。
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句の部分に相当)
[{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は、処理の意味をかみ砕くと以下のようなイメージになる。
lst = list()
for r in rws:
vle = r+ex
y = dict(zip(clm,vle)
lst.append(y)
(vleがテーブルに格納する値、clmがテーブル列名に相当し、それら2つのシーケンシャルをZIP()でリスト化して辞書型yにしたものを、リストlstに順次追記する処理をforループで繰り返す的な意味合い)