--- /dev/null
+from sqlalchemy import *\r
+\r
+class NoSuchTableError(SQLAlchemyError): pass\r
+\r
+# metaclass is necessary to expose class methods with getattr, e.g.\r
+# we want to pass db.users.select through to users._mapper.select\r
+class TableClassType(type):\r
+ def insert(cls, **kwargs):\r
+ o = cls()\r
+ o.__dict__.update(kwargs)\r
+ return o\r
+ def __getattr__(cls, attr):\r
+ if attr == '_mapper':\r
+ # called during mapper init\r
+ raise AttributeError()\r
+ return getattr(cls._mapper, attr)\r
+\r
+def class_for_table(table):\r
+ klass = TableClassType('Class_' + table.name.capitalize(), (object,), {})\r
+ def __repr__(self):\r
+ import locale\r
+ encoding = locale.getdefaultlocale()[1]\r
+ L = []\r
+ for k in self.__class__.c.keys():\r
+ value = getattr(self, k, '')\r
+ if isinstance(value, unicode):\r
+ value = value.encode(encoding)\r
+ L.append("%s=%r" % (k, value))\r
+ return '%s(%s)' % (self.__class__.__name__, ','.join(L))\r
+ klass.__repr__ = __repr__\r
+ klass._mapper = mapper(klass, table)\r
+ return klass\r
+\r
+class SqlSoup:\r
+ def __init__(self, *args, **kwargs):\r
+ """\r
+ args may either be an SQLEngine or a set of arguments suitable\r
+ for passing to create_engine\r
+ """\r
+ from sqlalchemy.engine import SQLEngine\r
+ # meh, sometimes having method overloading instead of kwargs would be easier\r
+ if isinstance(args[0], SQLEngine):\r
+ engine = args.pop(0)\r
+ if args or kwargs:\r
+ raise ArgumentError('Extra arguments not allowed when engine is given')\r
+ else:\r
+ engine = create_engine(*args, **kwargs)\r
+ self._engine = engine\r
+ self._cache = {}\r
+ def delete(self, *args, **kwargs):\r
+ objectstore.delete(*args, **kwargs)\r
+ def commit(self):\r
+ objectstore.get_session().commit()\r
+ def rollback(self):\r
+ objectstore.clear()\r
+ def _reset(self):\r
+ # for debugging\r
+ self._cache = {}\r
+ self.rollback()\r
+ def __getattr__(self, attr):\r
+ try:\r
+ t = self._cache[attr]\r
+ except KeyError:\r
+ table = Table(attr, self._engine, autoload=True)\r
+ if table.columns:\r
+ t = class_for_table(table)\r
+ else:\r
+ t = None\r
+ self._cache[attr] = t\r
+ if not t:\r
+ raise NoSuchTableError('%s does not exist' % attr)\r
+ return t\r