[Data-modeling] "Mentions" and "Mentioned In" - locked down types and community

Scott Meyer sm at metaweb.com
Fri Feb 13 22:23:48 UTC 2009


spencer kelly wrote:

> I'm speaking about locked types- that a type I make will not be
> developed in structure by anyone but me- and whose format is limited
> by my particular effort and understanding.
> 
> Indeed the whole point of freebase is to develop a collaborative
> network, and this has been achieved in every ounce on the technology
> side, but how often have you run into duplicate types, or tried to
> reciprocate a type whose creator has vanished and hasn't logged in for
> months? What will happen when we all die? The reason for schema
> lockdown is to provide stable properties for developers. Which (though
> I'm prepared'o be wrong) could be achieved by freezing a freebase 1.0
> and then loosening up types in our live version.  Default
> zero-permission types are the most un-wiki part of the freebase, a
> glaring contrast to the crowd-source model on which it has chosen to
> be built.

One of the reasons for the lock down is indeed to provide
a stable interface for application developers.  As the key
distinction between a database and a wiki is applications,
this is important.

However, this isn't the primary reason.  The primary reason is
that we need to preserve equality of effort. My 5 minutes should be
worth no more than your five minutes.  If we allow unrestricted
modification of types, we have a problem in that the person modifying
the type, can, in a single operation, scrap the work of thousands
of other people.

So what to do when you want to modify a type and you don't have
permissions?  Create your own type and use property delegation
to borrow whatever properties you want from type you lack permissions
to modify.  Delegating a property causes the types to share the
same property so your type will have all the data from the donor type.

I've attached some basic python code which demonstrates type
creation and property delegation.  When doing complex type surgery,
the best procedure that I've found is to write a python program
which does what you want, debug the program against sandbox
and then when all is working as desired, make the changes in
freebase.

Kind Regards,

-Scott


import simplejson
import urllib
from freebase.api import HTTPMetawebSession, MetawebError

mss = HTTPMetawebSession( 'sandbox.freebase.com', 'your-account', 'your-password' )
mss.login()

def key_exists( s, k ):
    q = {
        "id" : k,
        "guid" : None }
    return not None == s.mqlread( q )

def create_type( s, name, key, ns, cvt=None, tip=None ):
    if key_exists( s, ns + "/" + key ):
        return
    q = {
        "create" : "unconditional",
        "type" : "/type/type",
        "/type/type/domain" : { "connect" : "insert", "id" : ns },
        "name" : {"connect" : "insert", "value" : name, "lang" : "/lang/en" },
        "key" : {
            "connect" : "insert",
            "value" : key,
            "namespace" : ns }}
    if cvt:
        q['/freebase/type_hints/mediator'] = { "connect" : "update", "value" : True }
    if tip:
        q['/freebase/documented_object/tip'] = { "connect" : "update", "value" : tip, "lang" : "/lang/en" }
    s.mqlwrite( q )

def create_property( s, name, key, type, ect, unique, disambig=False, tip=None, extra=None ):
    if key_exists( s, type + "/" + key ):
        return
    q = {
        "create" : "unconditional",
        "type" : "/type/property",
        "name" : name,
        "key" : {
            "connect" : "insert",
            "value" : key,
            "namespace" : type },
        "schema" : { "connect" : "insert", "id" : type },
        "expected_type" : { "connect" : "insert", "id" : ect },
        "unique" : { "connect" : "update", "value" : unique }}
    if tip:
        q['/freebase/documented_object/tip'] = { "connect" : "update", "value" : tip, "lang" : "/lang/en" }
    if disambig:
        q['/freebase/property_hints/disambiguator'] = { "connect" : "update", "value" : True }
    if extra:
        q.update( extra )
    s.mqlwrite( q )

def delegate_property( s, p, type, ect=None ):
    q = {
        "id" : p,
        "type" : "/type/property",
        "name" : None,
        "unique" : None,
        "expected_type" : None,
        "key" : None,
        "/freebase/documented_object/tip" : None,
        "/freebase/property_hints/disambiguator" : None }
    r = s.mqlread( q )
    if not ect:
        ect = r["expected_type"]
    create_property( s, r["name"], r["key"], type, ect, r["unique"],
        r["/freebase/property_hints/disambiguator"],
        r["/freebase/documented_object/tip"],
        { "/type/property/delegated" : p } )

def reciprocate_property( s, rp, name, key, type, unique, disambig=False, tip=None, extra=None ):
    q = {
        "id" : rp,
        "/type/property/expected_type" : None }
    r = s.mqlread( q )
    ect = r["/type/property/expected_type"]
    create_property( s, name, key, type, ect, unique, disambig, tip,
        { "/type/property/master_property" : rp } )

def make_subclass( s, sub, super ):
    q = {
        "id" : super,
        "type" : "/type/type",
        "properties" : [{"id" : None}] }
    r = s.mqlread( q )
    for p in map( lambda( x ): x['id'], r['properties'] ):
        delegate_property( s, p, sub )
    w = {
        "id" : sub,
        "/freebase/type_hints/included_types" : { "connect" : "insert", "id" : super }}
    s.mqlwrite( w )



More information about the Data-modeling mailing list