patternpythonMinor
Elixir db model
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
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.
That's really nested which is bad sign. I suggest something like:
Or if you use the Null Object pattern:
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.ValueThat'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.ValueOr if you use the Null Object pattern:
@property
def Label(self):
return self.find_field(self.AssetType.label).ValueCode 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).ValueContext
StackExchange Code Review Q#3888, answer score: 3
Revisions (0)
No revisions yet.