HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Elixir db model

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
elixirmodelstackoverflow

Problem

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 '' % 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', Unico

Solution

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

Code Snippets

@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
@property
def Label(self):
    if self.AssetType:
       label = self.AssetType.Label
       field = self.find_field(label)
       if field:
           return field.Value
@property
def Label(self):
    return self.find_field(self.AssetType.label).Value

Context

StackExchange Code Review Q#3888, answer score: 3

Revisions (0)

No revisions yet.