3
\$\begingroup\$

I have designed this model which is very flexible. For example, you can create asset types, assets and combinations of them infinitely. It is the front end to a Python Pyramid website, so all the validation and business logic is handled by the web app.

However, not being a db guy, I have this sneaking suspicion that the schema totally sucks. There may be performance issues etc that I haven't foreseen etc.

class Asset(Entity):
    has_field('TimeStamp', Unicode, nullable=False)
    has_field('Modified', Unicode)
    belongs_to('AssetType', of_kind='AssetType', inverse='Assets')
    has_many('Values', of_kind='Value', inverse='Asset')
    Assets = ManyToMany('Asset')

    @property  
    def Label(self):
        if self.AssetType:
            for f in self.AssetType.Fields:
                if f.Label:
                    if self.Values:
                        for v in self.Values:
                            if v.Field.Name == f.Name:
                                return v.Value

    def __repr__(self):
        return '<Asset | %s>' % self.id

class AssetType(Entity):
    has_field('Name', Unicode, primary_key=True)
    has_field('Plural', Unicode)
    has_many('Assets', of_kind='Asset', inverse='AssetType')
    has_many('Fields', of_kind='Field', inverse='AssetType')

class Value(Entity):
    has_field('Value', Unicode)
    belongs_to('Asset', of_kind='Asset', inverse='Values')
    belongs_to('Field', of_kind='Field', inverse='Values')

class Field(Entity):
    has_field('Name', Unicode)
    has_field('Unique', Unicode, default=False)
    has_field('Label', Boolean, default=False)
    has_field('Searchable', Boolean, default=False)
    has_field('Required', Boolean, default=False)
    has_many('Values', of_kind='Value', inverse='Field')
    belongs_to('FieldType', of_kind='FieldType', inverse='Fields')
    belongs_to('AssetType', of_kind='AssetType', inverse='Fields')

class FieldType(Entity):
    has_field('Name', Unicode, primary_key=True)
    has_field('Label', Unicode, unique=True)
    has_many('Fields', of_kind='Field', inverse='FieldType')
\$\endgroup\$
3
\$\begingroup\$

You've reinvented a database inside a database. Basically, the Asset/AssetType is a simulation of a database inside a database which will as a result be slow. Also, you are going to spend a lot of effort reimplementing database features.

You could do this by using a NoSQL database which is designed to handle less structured data might be a good idea. Or you could create a table for each asset type which will perform better.

@property  
def Label(self):
    if self.AssetType:
        for f in self.AssetType.Fields:
            if f.Label:
                if self.Values:
                    for v in self.Values:
                        if v.Field.Name == f.Name:
                            return v.Value

That's really nested which is bad sign. I suggest something like:

@property
def Label(self):
    if self.AssetType:
       label = self.AssetType.Label
       field = self.find_field(label)
       if field:
           return field.Value

Or if you use the Null Object pattern:

@property
def Label(self):
    return self.find_field(self.AssetType.label).Value
\$\endgroup\$
4
  • \$\begingroup\$ Thanks @Winston, you're right about the db in the db idea. I'm a bit scared of locking the schema because the business rules here are changing rapidly. I had a look at CouchDB which is very flexible, but I can't get my head around map/reduce. I'll take a look at NoSQL. Failing that, I think I'll take your advice and just structure it. Thanks for the rewrites above too, I learned a lot. \$\endgroup\$
    – MFB
    Aug 5 '11 at 4:37
  • \$\begingroup\$ ok CouchDB IS NoSQL... and it's documentation has come a long way since I first looked into it. CouchDB is exactly what I need for a db in this case, and as it turns out, it will probably suffice as a web server too. Woot! \$\endgroup\$
    – MFB
    Aug 7 '11 at 22:26
  • \$\begingroup\$ @MFB, The fact that your business rules are changing shouldn't drive you to NoSQL. In that case, I'm just going to constantly update the schema. \$\endgroup\$ Aug 10 '11 at 12:52
  • \$\begingroup\$ you're right. It's not my only reason for looking at Couch. The more I look at Couch though, the more sense it makes to me, for this application at least. Almost everything in my business model can be described as an asset (or Document). The flexibility to continually add and subtract keys is just a huge bonus. \$\endgroup\$
    – MFB
    Aug 11 '11 at 13:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.