I have a unique ID field of type int in my documents. I'm doing ensureIndex on this field, but my documents still contain _id. Can I get rid of it?
From the docs ...
If a user tries to insert a document without providing an _id field,
the database will automatically generate an object id and store it
the _id field.
However, you can assign your own value to _id ...
The _id value may be of any type, other than arrays, so long as it is
a unique.
The better question is why would you create your own unique ID, build an index on it and remove the very useful ObjectID _id that is auto indexed?
All the official drivers use ObjectID and it has a lot of really good aspects to it:
It has a timestamp built in (so you don't need to store a date field
in your document, and you can use it to order by date.)
It is a "global, uniformly increasing sequence number" --- i.e.
it'll still be unique across servers if you need to shard your data,
etc.
No, you can't get rid of it, it is there by design, but you can map your unique identifier int to the _id itself when inserting documents.
A good idea would to store your hash into the _id field.
Thus, the database won't create automatically the _id field because it will already exist and you will save the space of an unused index.
Just set the _id field as any other with the value you want (your hash for instance). But be careful, it needs to be unique !
To ensure unicity you should either make it unique or put a subdocument in the _id field :
{ _id : { h : [yourHash], u : [a unique identifier]} , ...}
Related
I need to store matches in my database and those matches already have a unique ID where they come from. For further assistance and referring, it is best for me to keep this ID:
match = Match(id=my8digitsid)
match.save()
However, incoming matches (not played yet) don't have an ID yet. Can I safely save my match as follow:
match = Match()
match.save
And then, once the match played modify it as such:
match.id = my8digitsid
When I say safely, I mean whether or not that the default ID generated (auto-incremented I guess) is unique and won't have any conflicts with my self-made IDs.
Yes, you can be sure that the ORM will make unique id's as referred in the documentation here. The database is the one calculating the new number.
If a model has an AutoField — an auto-incrementing primary key — then
that auto-incremented value will be calculated and saved as an
attribute on your object the first time you call save():
>>> b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.')
>>> b2.id # Returns None, because b doesn't have an ID yet.
>>> b2.save()
>>> b2.id # Returns the ID of your new object. There’s no way to tell what the value of an ID will be before you call save(), because
that value is calculated by your database, not by Django.
For convenience, each model has an AutoField named id by default
unless you explicitly specify primary_key=True on a field in your
model.
You can also provide the Id if you want using this. I copy below the info from Django documentation.
Explicitly specifying auto-primary-key values If a model has an
AutoField but you want to define a new object’s ID explicitly when
saving, just define it explicitly before saving, rather than relying
on the auto-assignment of the ID:
>>> b3 = Blog(id=3, name='Cheddar Talk', tagline='Thoughts on cheese.')
>>> b3.id # Returns 3.
>>> b3.save()
>>> b3.id # Returns 3.
If you assign auto-primary-key values manually, make sure not to use
an already-existing primary-key value! If you create a new object with
an explicit primary-key value that already exists in the database,
Django will assume you’re changing the existing record rather than
creating a new one.
Given the above 'Cheddar Talk' blog example, this example would
override the previous record in the database:
b4 = Blog(id=3, name='Not Cheddar', tagline='Anything but cheese.')
b4.save() # Overrides the previous blog with ID=3!
But I don't recommend You to assign that ID yourself. I think more convenient to create a field of the model with the ID from where they come from.
The reason Why I don't recommend this is because you will have to verify always that the id provided has not been used before before inserting it. As a general rule I try to avoid modifying the standard behaviour of Django as much as possible.
I wanted to know is there anything equivalent to:
select columnname from tablename
Like Django tutorial says:
Entry.objects.filter(condition)
fetches all the objects with the given condition. It is like:
select * from Entry where condition
But I want to make a list of only one column [which in my case is a foreign key]. Found that:
Entry.objects.values_list('column_name', flat=True).filter(condition)
does the same. But in my case the column is a foreign key, and this query loses the property of a foreign key. It's just storing the values. I am not able to make the look-up calls.
Of course, values and values_list will retrieve the raw values from the database. Django can't work its "magic" on a model which means you don't get to traverse relationships because you're stuck with the id the foreign key is pointing towards, rather than the ForeignKey field.
If you need to filters those values, you could do the following (assuming column_name is a ForeignKey pointing to MyModel):
ids = Entry.objects.values_list('column_name', flat=True).filter(...)
my_models = MyModel.objects.filter(pk__in=set(ids))
Here's a documentation for values_list()
To restrict a query set to a specific column(s) you use .values(columname)
You should also probably add distinct to the end, so your query will end being:
Entry.objects.filter(myfilter).values(columname).distinct()
See: https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.values
for more information
Depending on your answer in the comment, I'll come back and edit.
Edit:
I'm not certain if the approach is right one though. You can get all of your objects in a python list by getting a normal queryset via filter and then doing:
myobjectlist = map(lambda x: x.mycolumnname, myqueryset)
The only problem with that approach is if your queryset is large your memory use is going to be equally large.
Anyway, I'm still not certain on some of the specifics of the problem.
You have a model A with a foreign key to another model B, and you want to select the Bs which are referred to by some A. Is that right? If so, the query you want is just:
B.objects.filter(a__isnull = False)
If you have conditions on the corresponding A, then the query can be:
B.objects.filter(a__field1 = value1, a__field2 = value2, ...)
See Django's backwards relation documentation for an explanation of why this works, and the ForeignKey.related_name option if you want to change the name of the backwards relation.
I have a database schema where attribute are unlimited, I can have this structure using two ways.
Using Entity attribute-value model
table 1
id
entity
table 2
entityid
attribute-name
attribute-value
2 . Way is to use JSON.
like
table1
id
entity
json-attribute {"name":"value-pair"}
I have a question which way will be best and effective .
I am not familiar with a DBMS that would let you efficiently find all entities where someAttribute = x, if the entities were stored in a non-deconstructed canonical JSON representation. (But I would be eager to know about any.)
The first approach using two tables (at least) can accomplish this task, and it is therefore the more capable and the more flexible approach; a JSON representation of the entity always be constructed from the database recordset:
// all entities having a particular attribute
select entityid, attributeName, attributeValue
from ENTITIES INNER JOIN ENTITYATTRIBUTES
on ENTITY.ID = ENTITYATTRIBUTES.entityid
where ENTITIES.id IN
(
select distinct entityid from ENTITYATTRIBUTES
where attributename = ? and attributeValue = ?
)
OR
// the attributes for a specified entity
select attributeName, attributeValue
from ENTITIES INNER JOIN ENTITYATTRIBUTES
on ENTITY.ID = ENTITYATTRIBUTES.entityid
where ENTITIES.id = ?
Complexity could enter, of course, if attributes could themselves contain entities. Nesting of objects is possible in the JSON representation but in the database it requires either a multi-table relational mapping or an OODBMS that supports nested tables.
I had chosen json solution.
why ?
It will avoid writing complex query to fetch data.
What about if I need to load any particular attribute ?
yes. In JSON solution I have to load all attribute from the database. and then filter for that particular attribute.
But in my case I will be loading all attribute every time.
If I have a condition of loading particular attribute I might have chosen attribute value schema.
Is it possible to map to methods instead of properties?
I have a Customer class with a method "GetOrders()" typeof "ReadOnlyCollection" with backing field "_orders" typeof "IList".
I tried in CustomerMap:
HasMany<Order>(Reveal.Member<Customer>("_orders"))
.KeyColumn("CustomerId").Cascade.All().Inverse().Not.LazyLoad();
But I get an exception when running the insert for a customer containing 1 order.
Cannot insert the value NULL into column 'CustomerId', table 'Order';
column does not allow nulls. INSERT fails.
Does mapping methods (or at least their backing fields) not work?
Or am I doing something else wrong?
The problem was that I did not map the Customer to the Orders also.
I have a model that contains a foreign key value, then in the form generated from this model, I want to auto select the record's key according to the record I'm adding the form's contents to...I've tried the below code, but it tells me QuerySet doesn't contain vehicle
stock = Issues.objects.filter(vehicle=id)
form = IssuesForm(initial={'id_vehicle': stock.vehicle})
I'm a bit new to django btw so any ideas are highly appreciated
filter always gives a QuerySet, which is a set of values. If you just want a single object, you should use get.
However I don't really understand why you need to do the lookup at all. You have the id value already, since you are using it to look up stock. So why don't you just pass id as the value for id_vehicle?