I have two unrelated tables with the same primary key.
ip mac
11.11.11.11 48-C0-09-1F-9B-54
33.33.33.33 4E-10-A3-BC-B8-9D
44.44.44.44 CD-00-60-08-56-2A
55.55.55.55 23-CE-D3-B1-39-A6
ip type owner
22.22.22.22 laptop John Doe
33.33.33.33 server XYZ Department
44.44.44.44 VM Mary Smith
66.66.66.66 printer ZWV Department
The first table is automatically refreshed every minute. I can't change the database structure or the script that populates it.
Both tables have ip
as PRIMARY KEY.
In a view, I would like to display a table like this:
ip mac type owner Alert
11.11.11.11 48-C0-09-1F-9B-54 Unauthorized
55.55.55.55 23-CE-D3-B1-39-A6 Unauthorized
22.22.22.22 laptop John Doe Down
66.66.66.66 printer ZWV Department Down
33.33.33.33 4E-10-A3-BC-B8-9D server XYZ Department OK
44.44.44.44 CD-00-60-08-56-2A VM Mary Smith OK
How can I model this? Should I make one of the two primary keys a foreign key into the other one?
Once the code is in operation, there will be lots of data, so I want to make sure it's fast enough.
What is the fastest way to retrieve the data?
Update:
I tried using OneToOneField
for the second table.
This helps me get records that are in both tables, and the records for unauthorized devices (IPs missing in second table):
ip mac type owner Alert
11.11.11.11 48-C0-09-1F-9B-54 Unauthorized
55.55.55.55 23-CE-D3-B1-39-A6 Unauthorized
33.33.33.33 4E-10-A3-BC-B8-9D server XYZ Department OK
44.44.44.44 CD-00-60-08-56-2A VM Mary Smith OK
but I can't get the devices that are down (IP's missing in first table):
22.22.22.22 laptop John Doe Down
66.66.66.66 printer ZWV Department Down
I asked for help here, but it seems it can't be done with OneToOneField
Since
ip
is primary key in both an the first table is getting updated frequently, I suggest updating the second table and converting theip
in the second table to haveip
of the first table as aOneToOneField
.This is how your models should look like:
docs
You can also have the one to one relation using a separate column:
So now you can have the ip address as the primary key, and you can still refer to the table
ModelA
using the fieldmodelA
.Once you have a value from one of both tables just do a query into the other one, looking for id. Since these two tables are separated you must do an extra query. You don't need to create an explicit relation, since you are looking into its "id/ip". So once you have a first value, named 'first_object', just look for its relative into the other table.
Then if you want just 'add' the desired columns to the other model and sent a single object to whatever you want:
General idea
You can use qs.union:
class Meta: managed = False
Generic approach for multiple fields
A more complex but "universal" approach may use
Model._meta.get_fields()
. It will be easier to use for cases where "second" model have more that 1 extra field (not onlyip,mac
). Example code (not tested, but gives general impression):Using OneToOneField for "better" SQL
Theoretically you can use
device_info = models.OneToOneField(OperationalDevice, db_column='ip', primary_key=True, related_name='status_info')
: inAllowedDevice
. In this case your first QS may be defined without use ofSubquery
:P.S. To automate models definition you can use
manage.py inspectdb
P.P.S. Maybe multi-table inheritance with custom
OneToOneField(..., parent_link=True)
may be more helpful for you than usingunion
.