Data Mapping

解説は土日に。

One to OneとOne to Manyのプログラムです。
Many to Manyは書きかけ&うまく動いてくれないので
明日にでも。

プログラム的にはJSONファイルを読み込み、データベースに格納
データベースからデータを引っ張り出してマッピングという流れです。

使用するJSONファイルは以下になります。

{
"users_table": [
["1", "Jane", "enaj"],
["2", "John", "j0hn"],
["3", "Kevin", "kEv1n"]
],
"emails_table": [
["1", "jane@street.net", "1"],
["2", "smith@street.net", "1"],
["3", "j.smith@story.com", "1"],
["4", "john@dog.org", "2"],
["5", "john@kevin-and-john.com", "2"],
["6", "kevin@kevin-and-john.com", "3"]
]
}


from simplejson import *
from sqlalchemy import *

# ActivePython(2.4.3.12)
# SimpleJson(1.3.0)
# SQLAlchemy(0.2.3)
# pysqlite(2.3.1)
SQLite(3.3.6)

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

#One to One/Many to One

#makeshift->
jsonObj = load(file('twisted_mind.json', 'r'), \
     encoding='utf-8')
#<-makeshift

metadata = BoundMetaData('sqlite:///', echo=False)

#makeshift->
users_table = Table('users', metadata,
    Column('user_id', Integer, primary_key=True),
    Column('user_name', String(20)),
    Column('password', String(20)),)

emails_table = Table('emails', metadata,
    Column('mail_id', Integer, primary_key=True),
    Column('address', String(40)),
    Column('user_id', Integer, ForeignKey('users.user_id')),)

metadata.create_all()

for row in jsonObj['users_table']:
    i = users_table.insert()
    i.execute(
        user_id=row[0],
        user_name=row[1],
        password=row[2])

for row in jsonObj['emails_table']:
    i = emails_table.insert()
    i.execute(
        mail_id=row[0],
        address=row[1],
        user_id=row[2])
#<-makeshift

#users_table = Table('users', metadata, autoload=True)
#emails_table = Table('emails', metadata, autoload=True)

#create_session(echo_uow=True)
session = create_session()

class User(object):
    def __init__(self, user_name, password):
        self.user_id = None
        self.user_name = user_name
        self.password = password
    def __repr__(self):
        pass
    def __call__(self):
        pass

class Email(object):
    def __init__(self, address=None):
        self.mail_id = None
        self.address = address
        self.user_id = None
    def __repr__(self):
        return repr(self.address)

#mapper(User, users_table, properties={
#    'address': relation(mapper(Email, emails_table))})

mapper(Email, emails_table)
mapper(User, users_table, properties={
    'address': relation(Email)})

mike = User(user_name='Mike', password='ekim')
mike.address.append(Email('mike@horizon.com'))
mike.address.append(Email('mike@english.com'))

session.save(mike)
session.flush()

clear_mappers()

# Backreferences
mapper(Email, emails_table)
mapper(User, users_table, properties=dict(
    emails=relation(Email, backref='user'),))

mike = session.query(User).get_by(user_name='Mike')
email = Email('mike@hi.com')
email.user = mike

session.save(mike)
session.flush()

clear_mappers()

mapper(Email, emails_table)
#cascade='all, delete-prphan'
mapper(User, users_table, properties=dict(
    emails=relation(Email,
        backref=backref('user', cascade='all, delete-orphan'), lazy=False),))

mike = session.query(User).get_by(user_name='Mike')

session.delete(mike)
session.flush()

clear_mappers()

#Overriding Column Names
#Deferred Column Loading
mapper(User, users_table, properties={
    'id': users_table.c.user_id,
    'name': deferred(users_table.c.user_name),
    'emails': relation(mapper(Email, emails_table),
        backref=backref('user', cascade="all, delete-orphan",
        lazy=False)),})

# user_name -> name
john = session.query(User).get_by(name='John')

"""
>>> john.name
'John'
>>> john.id
2
"""
john.name
john.id

session.flush()
clear_mappers()

run(users_table.select())
run(emails_table.select())