Many to Many and Add Data

上記を少々改造してみました。


from sqlalchemy import *

engine = create_engine('sqlite:///')
engine.echo = False
engine.echo_uow = False

def run(stmt):
    rs = stmt.execute()
    for row in rs:
        print row
    else:
        print

metadata = BoundMetaData(engine)

info_table = Table('infos', metadata,
    Column('pk', Integer, primary_key=True),
    Column('info', String))

data_table = Table('data', metadata,
    Column('pk', Integer, primary_key=True),
    Column('data_val', String))

rel_table = Table('rels', metadata,
    Column('info_pk', Integer, ForeignKey(info_table.c.pk)),
    Column('data_pk', Integer, ForeignKey(data_table.c.pk)))

metadata.create_all()

info_table.insert().execute(
    {'pk':1, 'info':'pk_1_info'},
    {'pk':2, 'info':'pk_2_info'},
    {'pk':3, 'info':'pk_3_info'},
    {'pk':4, 'info':'pk_4_info'},
    {'pk':5, 'info':'pk_5_info'})

rel_table.insert().execute(
    {'info_pk':1, 'data_pk':10},
    {'info_pk':1, 'data_pk':11},
    {'info_pk':1, 'data_pk':12},
    {'info_pk':1, 'data_pk':13},
    {'info_pk':2, 'data_pk':10},
    {'info_pk':2, 'data_pk':21},
    {'info_pk':2, 'data_pk':10},
    {'info_pk':2, 'data_pk':23},
    {'info_pk':3, 'data_pk':30},
    {'info_pk':3, 'data_pk':31},
    {'info_pk':3, 'data_pk':32},
    {'info_pk':3, 'data_pk':33})

data_table.insert().execute(
    {'pk':10, 'data_val':'10_data'},
    {'pk':11, 'data_val':'11_data'},
    {'pk':12, 'data_val':'12_data'},
    {'pk':13, 'data_val':'13_data'},
    {'pk':20, 'data_val':'20_data'},
    {'pk':21, 'data_val':'21_data'},
    {'pk':22, 'data_val':'22_data'},
    {'pk':23, 'data_val':'23_data'},
    {'pk':30, 'data_val':'30_data'},
    {'pk':31, 'data_val':'31_data'},
    {'pk':32, 'data_val':'32_data'},
    {'pk':33, 'data_val':'33_data'})

class Information(object):
    def __init__(self, info):
        self.info = info
    def __repr__(self):
        return self.info

class Data(object):
    def __init__(self, data_val):
        self.data_val = data_val
    def __repr__(self):
        return self.data_val

session = create_session()

#makeshift->
mapper(Data, data_table)
mapper(Information, info_table, properties=dict(
    datas=relation(Data,
                   secondary=rel_table,
                   lazy=None,
                   backref='info',
                   cascade="all, delete-orphan")))

def foo(info_temp, data_temp):
    info_index = session.query(Information).\
        selectfirst(info_table.c.info==info_temp)
    data_index = session.query(Data).\
        selectfirst(data_table.c.data_val==data_temp)
    
    i = None
    
    if info_index == None and data_index == None:
        i = Information(info_temp)
        i.datas.append(Data(data_temp))
    elif info_index == None and data_index != None:
        i = Information(info_temp)
        j = session.get(Data, data_index.pk)
        i.datas.append(j)
    elif data_index == None and info_index != None:
        i = session.get(Information, info_index.pk)
        i.datas.append(Data(data_info))
    else:
        i = session.load(Information, info_index.pk)
        j = session.load(Data, data_index.pk)
        i.datas.append(j)
    
    session.save(i)
    session.flush()

foo('pk_1_info', '10_data')
foo('pk_3_info', '33_data')

run(rel_table.select(order_by=[rel_table.c.info_pk, rel_table.c.data_pk]))

かなり無理矢理感があります…。
とくに関数部分は書いててすごく疑問になってました。

もっと簡単に書けるんじゃないのか?
ただ自分がSQLを知らなすぎるんじゃないか?

もっと簡単に書けるんでしょうね…。

勉強し直してリベンジ予定です。