Created
January 21, 2011 06:08
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""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