rom
rom copied to clipboard
Question on how to create a proper Many to many relation between enitites
Hi,
I need to store two entites, one is file system and another is client. they are mapped many to many in real world, means, multiple FSes could be mapped to one client, while mulit clients could be mapped to one FS at mean time, below is an exmpale,
I created two FS, FS_1, and FS_2 I then exposed FS1 to Client_1 and Client_2 I then exposed FS2 to Client_1 and Client_2
Then I am using the following models to persis them into the redis
class Client(rom.Model):
ip = rom.String(required=True, unique=True, index=True, prefix=True, suffix=True, keygen=rom.IDENTITY)
entries = rom.ManyToOne('Entry', on_delete='no action')
class Entry(rom.Model):
client = rom.OneToMany('Client')
fs = rom.OneToMany('FileSystem')
class FileSystem(rom.Model):
fs_name = rom.String(required=True, unique=True, index=True, prefix=True, suffix=True, keygen=rom.IDENTITY)
fs_type = rom.String(required=True )
fs_creation_time = rom.DateTime(required=True)
fs_mount_point = rom.String(required=True)
fs_is_mounted = rom.Boolean(required=True)
fs_is_dirty = rom.Boolean(required=True)
fs_is_deleted = rom.Boolean(required=True)
entries = rom.ManyToOne('Entry', on_delete='no action')
Them,I am going to use them like in below
entry1 = Entry()
client1 = Client(ip='1.2.3.4')
client1.entries=entry1
client1.save()
client2 = Client(ip='5.2.3.4')
client2.entries=entry1
client2.save()
fs_1 = FileSystem(fs_name='fs_1',
fs_type ='NFS',
fs_creation_time=datetime.now(),
fs_mount_point='/tmp{}'.format(0),
fs_is_mounted=random.choice([True,False]),
fs_is_dirty=random.choice([True,False]),
fs_is_deleted=random.choice([True,False]))
fs_1.entries=entry1
fs_1.save()
fs_2 = FileSystem(fs_name='fs_2',
fs_type ='NFS',
fs_creation_time=datetime.now(),
fs_mount_point='/tmp{}'.format(1),
fs_is_mounted=random.choice([True,False]),
fs_is_dirty=random.choice([True,False]),
fs_is_deleted=random.choice([True,False]))
fs_2.entries=entry1
fs_2.save()
However, I found it is quite inconnvient to add data on it, saying, I am now going to exposed FS3 to Client_1 only, what should I supposed to do?
I'm on vacation, and not really replying to email, so thank you for your patience. I'm also only carrying my mobile, so I'm not sure I can get you good code. But let me try to explain.
Generally speaking, I like to approach these kinds of problems by asking "what is shared?"
In this case, your clients aren't shared, but your filesystems might be. Things that are shared (like filesystems) should be the "one" side of a ManyToOne relationship.
Because you may need many filesystems with each client, the client also has to be the "one" side of the ManyToOne relationship.
Looking at your Entry, I'd set it up as:
class Entry(rom.Model): client = rom.ManyToOne('Client') fs = rom.ManyToOne('FileSystem') unique_together = [ ('fs', 'client'), ]
Then flip around your ManyToOne to OneToMany on your client and filesystem models.
The unique_together relationship prevents duplicates, and everything else should work the way you want.
Let me know if you have any questions,
- Josiah
On Tue, Dec 20, 2022, 6:48 AM wangyihanlarry @.***> wrote:
Hi,
I need to store two entites, one is file system and another is client. they are mapped many to many in real world, means, multiple FSes could be mapped to one client, while mulit clients could be mapped to one FS at mean time, below is an exmpale,
I created two FS, FS_1, and FS_2 I then exposed FS1 to Client_1 and Client_2 I then exposed FS2 to Client_1 and Client_2
Then I am using the following models to persis them into the redis
class Client(rom.Model):
ip = rom.String(required=True, unique=True, index=True, prefix=True, suffix=True, keygen=rom.IDENTITY) entries = rom.ManyToOne('Entry', on_delete='no action')
class Entry(rom.Model):
client = rom.OneToMany('Client') fs = rom.OneToMany('FileSystem')
class FileSystem(rom.Model):
fs_name = rom.String(required=True, unique=True, index=True, prefix=True, suffix=True, keygen=rom.IDENTITY) fs_type = rom.String(required=True ) fs_creation_time = rom.DateTime(required=True) fs_mount_point = rom.String(required=True) fs_is_mounted = rom.Boolean(required=True) fs_is_dirty = rom.Boolean(required=True) fs_is_deleted = rom.Boolean(required=True) entries = rom.ManyToOne('Entry', on_delete='no action')
Them,I am going to use them like in below
entry1 = Entry()
client1 = Client(ip='1.2.3.4') client1.entries=entry1 client1.save() client2 = Client(ip='5.2.3.4') client2.entries=entry1 client2.save() fs_1 = FileSystem(fs_name='fs_1', fs_type ='NFS', fs_creation_time=datetime.now(), fs_mount_point='/tmp{}'.format(0), fs_is_mounted=random.choice([True,False]), fs_is_dirty=random.choice([True,False]), fs_is_deleted=random.choice([True,False])) fs_1.entries=entry1 fs_1.save() fs_2 = FileSystem(fs_name='fs_2', fs_type ='NFS', fs_creation_time=datetime.now(), fs_mount_point='/tmp{}'.format(1), fs_is_mounted=random.choice([True,False]), fs_is_dirty=random.choice([True,False]), fs_is_deleted=random.choice([True,False])) fs_2.entries=entry1 fs_2.save()
However, I found it is quite inconnvient to add data on it, saying, I am now going to exposed FS3 to Client_1 only, what should I supposed to do?
— Reply to this email directly, view it on GitHub https://github.com/josiahcarlson/rom/issues/158, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABTDQQ4AQQ7STQGTLH45ATWOGTIJANCNFSM6AAAAAATEOZ6M4 . You are receiving this because you are subscribed to this thread.Message ID: @.***>