Say we have the following class:
Class Alert(models.Model):
contact = models.ForeignKey('emails.Contact',null=True,blank=True)
If I wanted to get the foreign key of the contact I would do somealert.contact.pk or somealert.contact_id. Do these commands pull down the whole contact object and then get the key? Or do any of them just yield the foreign key without pulling all off the attributes of the instance from the database. I worried about performance and would prefer to just get the key itself.
The first one - somealert.contact.pk - will get the Contact object. The second - somealert.contact_id - won't.
You can verify this in the shell by looking at the contents of django.db.connection.queries.
Related
I am using Simple-Salesforce to query records via .query_all, but when I include a recently created custom field, I receive the No such column error.
An example of the query that creates the error is below, with Problem_Field__c as a stand-in for my field.
s.query_all('SELECT ID, Name, Problem_Field__c FROM Custom_Object___c')
I have already reviewed the field-level security of this field and do have access to it.
As additional information, my login to the sandbox in which I am using this custom field is below:
s = simple_salesforce.Salesforce(username='myUsername.TestDomain',
password='myPassword',
organizationId='mySandboxOrgId',
security_token='',
domain='test')
The problem field is a lookup field to the Contact object.
A lookup is a relationship between two objects. When you use a relationship in a query and the query is navigating the relationship in a child-to-parent direction (Contact = parent, your custom object = child), you must use the relationship names. Custom relationships are named with an __r rather than __c suffix (docs). The relationship name is typically the same as the API name of the lookup on Lookup definition screen but with suffix replaced. Your query should be
s.query_all('SELECT ID, Name, MyRelationship__r.Some_Contact_Field FROM Custom_Object___c')
To know the relationship name for sure, you can use take a look at the object schema.
I am working with Django 1.9 and noticed some strange behavior when working with the models. I know that the following code creates an object, saves it to the database, changes the field, then updates that same entry in the database:
cat = models.Cat(name="Bob")
cat.save()
cat.name = "Sally"
cat.save()
However, when I query all my objects using cats = models.Cat.objects.all() I find that rather than returning ["Sally"] it actually returns ["Bob", "Sally"]. Apparently cat.save() is creating a new element in the database rather than updating an existing one. I've worked with Django before, but never had this issue. One thing to note is that the name attribute is the primary key for the Cat model. Could this be why it's not updating, but creating a whole new entry?
The primary key is what Django uses to determine whether to update or create an item. Usually, that's an opaque ID which you don't modify; but in your case, it's part of your data. When you modify the value, Django has no way of knowing that the object refers to an existing row in the database.
Don't do this; stick with autoincremented IDs that have no relation to your actual data.
You're right, the issue here is that your primary key is the name field. Django will do an update if the pk value exists in the database, and an insert if it doesn't. For example:
class Cat(models.Model):
name = models.CharField(max_length=255)
cat = Cat(name='Bart')
cat.save() # This creates a new object
print(cat.pk)
> '1'
cat.name = 'Sally'
cat.save() # This updates the object, the pk will still be '1'
print(cat.pk)
> '1'
print(Cat.objects.all())
> [<Cat 'Sally'>]
fluffy = Cat(name='Fluffy')
fluffy.pk = 1
fluffy.save()
'''This will UPDATE the existing object, since an object
with that primary key already exists'''
print(Cat.objects.all())
> [<Cat 'Fluffy'>]
fluffy.pk = 2
fluffy.save()
'''This will CREATE a new object, since no object with
that primary key already exists'''
print(Cat.objects.all())
> [<Cat 'Fluffy'>, <Cat 'Fluffy'>]
If possible, I would recommend removing the primary_key=True attribute on the name field. If you want name to be unique, maybe just set unique=True instead?
I am writing a script and want to fake a User with an id (PK) of 2
var = Table(FKToUser=2)
var.save()
the problem is I'm getting :
"Table.FKToUser" must be a "User" instance
I've verified that the auth_user has a record with id=2
How can I fake this 2 value for testing purposes?
Thank you!
Assuming that Table is your model and FKToUser is a foreign key, there are two ways. The first is to set the FKToUser_id attribute to 2 and save the model. The other is to fetch the user and set the FKToUser attribute to the right user model instance.
This is also basically how a foreign key works. The actual column in the database is the FKToUser_id column, and it's a simple Integer foreign key to an id in another column. Django magic makes it possible to automatically retrieve the right instance by accessing FKToUser, and to set the right value by assigning a model instance to FKToUser.
I have tried to delete an entity from the GAE datastore for hours now and it doesn't work as it should. I pretty much did the same thing as how to delete NDB entity using ID?, however I'm sure the problem is with the ancestor relationship.
This is the relevant piece of code:
try:
ndb.Key('NewsBase', int(self.request.get('delid'))).delete()
When I print out the ndb.Key (self.request.out.write...) I get something like Key('NewsBase', 8008), which is the correct ID (checked in datastore). In the dashboard I also get the "Decoded entity key", which is
NewsBase: name=mynews > NewsBase: id=8001
I am a little confused on how to include the ancestor information but as far as I can tell from here Using Key in NDB to retrieve an entity I don't need it at all, or do I?
EDIT: How I create keys
def news_key(base_name='mynews'):
return ndb.Key('NewsBase', base_name)
t = NewsBase(parent=news_key('mynews'))
t.user = user
t.put()
You need the full key, including the ancestor if there is one. That's because the child ID by itself is not necessarily unique: only the full path is, so you need it to identify the particular entity.
In your case, you probably just want nb.Key('NewsBase', 'mynews', 'NewsBase', 8001).
(I suspect however that you are doing something strange to create your keys in the first place: it's unusual to have an ancestor, with a name key, of the same type as the numeric ID of the child.)
Try using the urlsafe version of the key instead of the ID:
Output the key as:
key.urlsafe() instead of key.id()
and delete it in your request handler as:
ndb.Key(urlsafe=self.request.get('delkey')).delete()
the urlsafe version of the key will contain all necessary ancestor information.
Also, does your news_key function know that the key its making exists? You should not store an entity with a parent key for an entity that does not exist.
You're news_key should probably be something more like:
def news_key(base_name='mynews'):
return NewsBase.get_or_insert(id=base_name).key
Just as an FYI - Deleting the parent does not delete all children. Also, the way you have it shown here, the Parent to your NewsBase entity will be another NewsBase entity.
I want to retrieve all of my Class entities key_names and not the Key.
Is there a way to do this with gae?
Here is my current code:
entities = db.GqlQuery("SELECT __key_name__ FROM Class").fetch(1000)
logging.info(entities)
which of course dosen't work because there is no property key_name. Does anyone know how to get the same effect?
I know how to return the Key property but what I want is the key_name.
The key contains the key name, of course. So when you've got a list of keys, you can call name() on each of them to get the name component.