Exemple #1
0
    def test_collection_with_backref(self):
        for base in (object, MyBaseClass, MyClass):
            class Post(base):pass
            class Blog(base):pass

            attributes.register_class(Post)
            attributes.register_class(Blog)
            attributes.register_attribute(Post, 'blog', uselist=False, extension=attributes.GenericBackrefExtension('posts'), trackparent=True, useobject=True)
            attributes.register_attribute(Blog, 'posts', uselist=True, extension=attributes.GenericBackrefExtension('blog'), trackparent=True, useobject=True)
            b = Blog()
            (p1, p2, p3) = (Post(), Post(), Post())
            b.posts.append(p1)
            b.posts.append(p2)
            b.posts.append(p3)
            self.assert_(b.posts == [p1, p2, p3])
            self.assert_(p2.blog is b)

            p3.blog = None
            self.assert_(b.posts == [p1, p2])
            p4 = Post()
            p4.blog = b
            self.assert_(b.posts == [p1, p2, p4])

            p4.blog = b
            p4.blog = b
            self.assert_(b.posts == [p1, p2, p4])

            # assert no failure removing None
            p5 = Post()
            p5.blog = None
            del p5.blog
Exemple #2
0
    def _post_init(self):
        if self._should_log_info:
            self.logger.info(str(self) + " setup primary join %s" % self.primaryjoin)
            self.logger.info(str(self) + " setup secondary join %s" % self.secondaryjoin)
            self.logger.info(str(self) + " synchronize pairs [%s]" % ",".join("(%s => %s)" % (l, r) for l, r in self.synchronize_pairs))
            self.logger.info(str(self) + " secondary synchronize pairs [%s]" % ",".join(("(%s => %s)" % (l, r) for l, r in self.secondary_synchronize_pairs or [])))
            self.logger.info(str(self) + " local/remote pairs [%s]" % ",".join("(%s / %s)" % (l, r) for l, r in self.local_remote_pairs))
            self.logger.info(str(self) + " relation direction %s" % self.direction)

        if self.uselist is None and self.direction is MANYTOONE:
            self.uselist = False

        if self.uselist is None:
            self.uselist = True

        if not self.viewonly:
            self._dependency_processor = dependency.create_dependency_processor(self)

        # primary property handler, set up class attributes
        if self.is_primary():
            if self.back_populates:
                self.extension = util.to_list(self.extension) or []
                self.extension.append(attributes.GenericBackrefExtension(self.back_populates))
                self._add_reverse_property(self.back_populates)
            
            if self.backref is not None:
                self.backref.compile(self)
        elif not mapper.class_mapper(self.parent.class_, compile=False)._get_property(self.key, raiseerr=False):
            raise sa_exc.ArgumentError("Attempting to assign a new relation '%s' to "
                "a non-primary mapper on class '%s'.  New relations can only be "
                "added to the primary mapper, i.e. the very first "
                "mapper created for class '%s' " % (self.key, self.parent.class_.__name__, self.parent.class_.__name__))
        
        super(RelationProperty, self).do_init()
Exemple #3
0
    def testlazytrackparent(self):
        """test that the "hasparent" flag works properly when lazy loaders and backrefs are used"""
        manager = attributes.AttributeManager()

        class Post(object):
            pass

        class Blog(object):
            pass

        # set up instrumented attributes with backrefs
        manager.register_attribute(
            Post,
            'blog',
            uselist=False,
            extension=attributes.GenericBackrefExtension('posts'),
            trackparent=True)
        manager.register_attribute(
            Blog,
            'posts',
            uselist=True,
            extension=attributes.GenericBackrefExtension('blog'),
            trackparent=True)

        # create objects as if they'd been freshly loaded from the database (without history)
        b = Blog()
        p1 = Post()
        Blog.posts.set_callable(b, lambda: [p1])
        Post.blog.set_callable(p1, lambda: b)
        manager.commit(p1, b)

        # no orphans (called before the lazy loaders fire off)
        assert getattr(Blog, 'posts').hasparent(p1, optimistic=True)
        assert getattr(Post, 'blog').hasparent(b, optimistic=True)

        # assert connections
        assert p1.blog is b
        assert p1 in b.posts

        # manual connections
        b2 = Blog()
        p2 = Post()
        b2.posts.append(p2)
        assert getattr(Blog, 'posts').hasparent(p2)
        assert getattr(Post, 'blog').hasparent(b2)
Exemple #4
0
    def get_extension(self):
        """Return an attribute extension to use with this backreference."""

        return attributes.GenericBackrefExtension(self.key)
Exemple #5
0
 def __init__(self, key, _prop=None, **kwargs):
     self.key = key
     self.kwargs = kwargs
     self.prop = _prop
     self.extension = attributes.GenericBackrefExtension(self.key)
Exemple #6
0
    def testbackref(self):
        class Student(object):
            pass

        class Course(object):
            pass

        manager = attributes.AttributeManager()
        manager.register_attribute(
            Student,
            'courses',
            uselist=True,
            extension=attributes.GenericBackrefExtension('students'))
        manager.register_attribute(
            Course,
            'students',
            uselist=True,
            extension=attributes.GenericBackrefExtension('courses'))

        s = Student()
        c = Course()
        s.courses.append(c)
        print c.students
        print[s]
        self.assert_(c.students == [s])
        s.courses.remove(c)
        self.assert_(c.students == [])

        (s1, s2, s3) = (Student(), Student(), Student())
        c.students = [s1, s2, s3]
        self.assert_(s2.courses == [c])
        self.assert_(s1.courses == [c])
        print "--------------------------------"
        print s1
        print s1.courses
        print c
        print c.students
        s1.courses.remove(c)
        self.assert_(c.students == [s2, s3])

        class Post(object):
            pass

        class Blog(object):
            pass

        manager.register_attribute(
            Post,
            'blog',
            uselist=False,
            extension=attributes.GenericBackrefExtension('posts'),
            trackparent=True)
        manager.register_attribute(
            Blog,
            'posts',
            uselist=True,
            extension=attributes.GenericBackrefExtension('blog'),
            trackparent=True)
        b = Blog()
        (p1, p2, p3) = (Post(), Post(), Post())
        b.posts.append(p1)
        b.posts.append(p2)
        b.posts.append(p3)
        self.assert_(b.posts == [p1, p2, p3])
        self.assert_(p2.blog is b)

        p3.blog = None
        self.assert_(b.posts == [p1, p2])
        p4 = Post()
        p4.blog = b
        self.assert_(b.posts == [p1, p2, p4])

        p4.blog = b
        p4.blog = b
        self.assert_(b.posts == [p1, p2, p4])

        class Port(object):
            pass

        class Jack(object):
            pass

        manager.register_attribute(
            Port,
            'jack',
            uselist=False,
            extension=attributes.GenericBackrefExtension('port'))
        manager.register_attribute(
            Jack,
            'port',
            uselist=False,
            extension=attributes.GenericBackrefExtension('jack'))
        p = Port()
        j = Jack()
        p.jack = j
        self.assert_(j.port is p)
        self.assert_(p.jack is not None)

        j.port = None
        self.assert_(p.jack is None)