Skip to content

Instantly share code, notes, and snippets.

@shazow
Created January 21, 2011 06:08
Show Gist options
  • Save shazow/789309 to your computer and use it in GitHub Desktop.
Save shazow/789309 to your computer and use it in GitHub Desktop.
SQLAlchemy declarative base with __export__ and __import__ useful for exporting and importing fixtures.
"""SQLAlchemy Metadata and Session object"""
from sqlalchemy import MetaData, types
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from datetime import datetime, date
__all__ = ['Session', 'metadata', 'BaseModel']
Session = scoped_session(sessionmaker(expire_on_commit=False))
metadata = MetaData()
# Map types class to (encode, decode) tuples.
# TODO: Need more conversion types
convert_types = {
types.LargeBinary: (
lambda o: o.encode('hex'),
lambda s: s.decode('hex')
),
types.DateTime: (
lambda o: o.strftime('%Y-%m-%d %H:%M:%S'),
lambda s: datetime.strptime(s, '%Y-%m-%d %H:%M:%S')
),
types.Date: (
lambda o: o.strftime('%Y-%m-%d'),
lambda s: date.strptime(s, '%Y-%m-%d')
),
}
class _Base(object):
def __export__(self):
d = {}
for col in self.__table__.columns:
encode, decode = convert_types.get(col.type.__class__, (lambda v: v, lambda v: v))
d[col.name] = encode(getattr(self, col.name))
return d
@classmethod
def __import__(cls, d):
params = {}
for k, v in d.items():
col = cls.__table__.columns.get(k)
if col is None:
continue
encode, decode = convert_types.get(col.type.__class__, (lambda v: v, lambda v: v))
params[str(k)] = decode(v)
return cls(**params)
BaseModel = declarative_base(metadata=metadata, cls=_Base)
""" Example:
class Foo(BaseModel):
...
f = Foo(...)
import json
s = json.dumps(f.__export__())
d = json.loads(s)
f2 = Foo.__import__(d)
assert f == f2
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment