rom icon indicating copy to clipboard operation
rom copied to clipboard

Question on how to create a proper Many to many relation between enitites

Open wangyihanlarry opened this issue 2 years ago • 1 comments

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?

wangyihanlarry avatar Dec 20 '22 12:12 wangyihanlarry

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: @.***>

josiahcarlson avatar Dec 27 '22 16:12 josiahcarlson