implement base merging
This commit is contained in:
parent
f683d07793
commit
f4a7441e86
39
kosokoso.py
39
kosokoso.py
|
|
@ -8,10 +8,11 @@ import pprint
|
|||
import sys
|
||||
# import traceback
|
||||
|
||||
Base = declarative_base()
|
||||
# this will get overridden by init_base
|
||||
Base = None
|
||||
|
||||
|
||||
class Tag(Base):
|
||||
class TagBase(object):
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.text == other.text
|
||||
|
|
@ -117,8 +118,7 @@ class Tag(Base):
|
|||
return c
|
||||
|
||||
|
||||
|
||||
class TagAssociation(Base):
|
||||
class TagAssociationBase(object):
|
||||
__tablename__ = "kk_tag_associations"
|
||||
db_id = sa.Column(sa.Integer, primary_key=True)
|
||||
tag_id = sa.Column(sa.Integer, sa.ForeignKey("kk_tags.db_id"))
|
||||
|
|
@ -131,7 +131,10 @@ class TagAssociation(Base):
|
|||
# m = sa.orm.mapper(Tag, Tag.__table__, non_primary=True,
|
||||
# primary_key=[Tag.text])
|
||||
# tag_obj = sa.orm.relationship(m)
|
||||
tag_obj = sa.orm.relationship(Tag)
|
||||
@declared_attr
|
||||
def tag_obj(self):
|
||||
return sa.orm.relationship(Tag)
|
||||
# tag_obj = sa.orm.relationship(Tag)
|
||||
|
||||
# FIXME doesn't work, may not be needed.
|
||||
# tag_obj = sa.orm.relationship("Tag", back_populates="collection")
|
||||
|
|
@ -152,7 +155,8 @@ class TagAssociation(Base):
|
|||
return "tag assoc %s: %s:%s" % (self.db_id,
|
||||
self.target_table, self.target_id)
|
||||
|
||||
class Taggable(Base):
|
||||
|
||||
class TaggableBase(object):
|
||||
__abstract__ = True
|
||||
|
||||
@declared_attr
|
||||
|
|
@ -197,6 +201,26 @@ class Taggable(Base):
|
|||
)
|
||||
|
||||
|
||||
def init_base(new_base):
|
||||
def init_cls(name, base):
|
||||
current = globals()[name + 'Base']
|
||||
new_ns = current.__dict__.copy()
|
||||
del new_ns['__dict__']
|
||||
new_ns = type(name, (new_base,), new_ns)
|
||||
globals()[name] = new_ns
|
||||
|
||||
for c in ['Tag', 'TagAssociation', 'Taggable']:
|
||||
init_cls(c, new_base)
|
||||
|
||||
globals()['Base'] = new_base
|
||||
sa.event.listen(Tag, 'before_insert', delete_before_insert)
|
||||
sa.event.listen(sa.orm.session.Session, 'before_flush',
|
||||
enforce_unique_text)
|
||||
return {'Tag': globals()['Tag'],
|
||||
'TagAssociation': globals()['TagAssociation'],
|
||||
'Taggable': globals()['Taggable']}
|
||||
|
||||
|
||||
def delete_before_insert(mapper, conn, target):
|
||||
# TODO figure out where exactly transactions happen.
|
||||
r = conn.execute("SELECT db_id FROM kk_tags WHERE text='%s'" %
|
||||
|
|
@ -214,6 +238,3 @@ def enforce_unique_text(session, flush_context, instances):
|
|||
if t:
|
||||
i.db_id = t.db_id
|
||||
|
||||
sa.event.listen(Tag, 'before_insert', delete_before_insert)
|
||||
sa.event.listen(sa.orm.session.Session, 'before_flush',
|
||||
enforce_unique_text)
|
||||
|
|
|
|||
|
|
@ -11,12 +11,11 @@ import unittest
|
|||
|
||||
import libkosokoso as kk
|
||||
|
||||
# TODO get this working -- merge bases?
|
||||
# DummyBase = sa.ext.declarative.declarative_base()
|
||||
class DummyBase(object):
|
||||
"""dummy"""
|
||||
DummyBase = sa.ext.declarative.declarative_base()
|
||||
kk.__dict__.update(kk.init_base(DummyBase))
|
||||
|
||||
class Foo(DummyBase, kk.Taggable):
|
||||
# TODO make it so DummyBase doesn't have to come after the mixin.
|
||||
class Foo(kk.Taggable, DummyBase):
|
||||
__tablename__ = 'foos'
|
||||
db_id = sa.Column(sa.Integer, primary_key=True)
|
||||
def __repr__(self):
|
||||
|
|
@ -25,7 +24,7 @@ class Foo(DummyBase, kk.Taggable):
|
|||
def __eq__(self, other):
|
||||
return self.db_id == other.db_id
|
||||
|
||||
class Bar(DummyBase, kk.Taggable):
|
||||
class Bar(kk.Taggable, DummyBase):
|
||||
__tablename__ = 'bars'
|
||||
db_id = sa.Column(sa.Integer, primary_key=True)
|
||||
def __repr__(self):
|
||||
|
|
@ -35,12 +34,15 @@ class ks_basic(unittest.TestCase):
|
|||
def setUp(self):
|
||||
# self.engine = sa.create_engine('sqlite://', echo=True)
|
||||
self.engine = sa.create_engine('sqlite://', echo=False)
|
||||
kk.Base.metadata.create_all(self.engine)
|
||||
DummyBase.metadata.create_all(self.engine)
|
||||
self.session = sa.orm.Session(self.engine)
|
||||
|
||||
def tearDown(self):
|
||||
del self.engine
|
||||
|
||||
# def debug(self):
|
||||
# pprint.pprint(kk.__dict__)
|
||||
|
||||
def test_add_as_object(self):
|
||||
a = Foo()
|
||||
self.session.add(a)
|
||||
|
|
@ -355,7 +357,7 @@ class ks_basic(unittest.TestCase):
|
|||
self.assertEqual(t3, kk.Tag('tag3'))
|
||||
|
||||
|
||||
# TODO test concurrent setting the same tag from different
|
||||
# TODO test concurrently setting the same tag from different
|
||||
# processes.
|
||||
|
||||
# TODO delete unused tags
|
||||
|
|
|
|||
Loading…
Reference in New Issue