Updating mongo collection - c++

I use mongodb and c++ driver for it and
when I update some collection of documents with fields entid, div, name, fld2 using this code:
connection.update("mydb.mycol", Query(bob().append("entid",1).obj()), bob().append("div", 5).obj());
updating has been done successfully, but updated document has not entid, name and fld2 fields. How can I update document without missing fields I do not need to update?

You need the $set modifier. I don't know anything about the C++ driver but the JS syntax is:
db.mydb.update({"entid" : 1}, {"$set" : {"div" : 5}})
I hope you can transform this to C++ code ;)

Related

Django annotate count in JSONField with Postgres

Using Django I have a field which is of type JSONField. I am wanting to get a distinct count on a nested key/value in the json. With a normal field you can just do soemthing like the following
model.objects.values('field_name')\
.annotate(total=Count('field_name')).order_by('-total')
This does not work for a JSONField.
Example Model
class Pet(models.Model):
data = JSONField()
Example of data
{
'name':'sparky',
'animal':'dog',
'diet':{
'breakfast':'biscuits',
'dinner':'meat',
}
}
Trying
Pet.objects.values('data__diet__dinner')\
.annotate(total=Count('data__diet__dinner')).order_by('-total')
Exception of
TypeError: unhashable type: 'list'
What is the correct way to execute this?
You can use jsonb_extract_path_text via a Func object as an alternative to the field transform:
Pet.annotate(dinner=Func(
F('data'), Value('diet'), Value('dinner'),
function='jsonb_extract_path_text')) \
.values('dinner') \
.annotate(total=Count('dinner'))
The reason why the field transform data__diet__dinner fails is an error within Django when you go deeper than just one level into the json structure and use GROUP BY in the SQL. The first level (name, animal, diet) should work fine.
The reason seems to be that for nested transforms, Django changes the SQL syntax used, switching from a single value to a list to specify the path into the json structure.
This is the syntax used for non-nested json transforms (= first level):
"appname_pet"."data" -> 'diet'
And this is the syntax used for nested transforms (deeper than first level):
"appname_pet"."data" #> ARRAY['diet', 'dinner']
While constructing the query, Django chokes on that list while working out the required GROUP BY clauses. This does not seem to be an inevitable restriction; the support for transforms is quite new, and this is possibly one of the kinks that haven't been worked out yet. So if you open a Django ticket, this might just work a few versions down the line.

Error database query using ManyToManyField on model

I'm fairly new to django web development. And I got an error whereby I try to change a 'post' under admin url - so localhost:8080/admin. I'm able to create it successfully but when I try to click the post that I had just added. I'm getting this error:
Exception Type: DatabaseError Exception Value: This query is not
supported by the database.
And this is the code that I know is 'messing' with this query:
#Post is an abstract class
class BlogPost(Post):
...
translators = models.ManyToManyField(Staff, related_name='translators')
photographers = models.ManyToManyField(Staff, related_name='photographers')
authors = models.ManyToManyField(Staff, related_name='authors')
...
To explain what is going on with this blog post - it can have multiple 'owners'/people that contributed to this post and thus the decision using ManyToManyField. And vice-versa with the 'Staff' member - the type of 'member' can have multiple ownership on multiple posts (Let me know if this logic doesn't make any sense because it does to me).
I'm using mongodb for the database, django 1.5.11 and I have installed djangotoolbox. I've tried the following solutions with adding a relationship to BlogPost as shown below:
Class Staff(Member):
...
staff_posts = models.ManyToManyField(BlogPost, related_name="staff_posts")
...
But I'm getting an error on 'cannot import BlogPost'. I tried figuring out the reason of this error and I don't think that I have a circular dependance - after checking all of the files, there's no circular dependance.
MongoDB (or mongoengine, which I'm guessing you're using) doesn't support joins, so the typical way to model many-to-many relations in a relational database has to be implemented some other way.
One way is to use a ReferenceField inside a ListField. It might look like this (not tested):
class BlogPost(Post):
authors = models.ListField(models.ReferenceField(Staff))
...
Also see these answers:
https://stackoverflow.com/a/18747306/98057
https://stackoverflow.com/a/25568877/98057
Just to put it out there, I'm not real familiar with MongoDB.
However, I don't believe you need to define a ManyToManyField on your Staff class. You already have a ManyToMany defined in your BlogPost, having it defined in one class file is all that is required. (At least for MySQL).

How can I set the value of objectID in algolia rails?

I am using algolia gem in my rails app. I am currently combining 3 different models into one index for a combined search of our case studies, blog posts and videos.
I am having trouble as indexing one model will overwrite objects from another model as Algolia appears to use the rails generated ID to map to objectID column.
posts.rb
algoliasearch auto_index: false, if: :open?, index_name: "combined_#{Rails.env}" do
attribute :objectID do
"p#{id}"
end
end
video.rb and case_studies.rb
In the same fashion I try to set attribute :objectID to "v#{id}" for videos as well as set attribute :objectID to "c#{id}" for case studies
This virtual attribute style did not work, so I attempted to create an actual string column on the db and reindex that way to no avail.
If anyone have any ideas here I would really appreciate it and I am running low.
You can use the custom ObjectID inside each of your Model.
Inside your model
def custom_algolia_id
"v#{id}"
end
algoliasearch id: :custom_algolia_id do
attribute :title, :length
end

Dynamically creating campaign using template id using mailsnake in django

I dynamically create campaign from my website using mailsnake in django framework. Want to add the data and images directly into campaign for that i add the html data into the sections like postcard_heading00, postcard_image, std_content00.
Write the code as below:
mailsnake = MailSnake('apikey')
template_option = {'list_id':xxxx, 'subject':'testing', 'from_email':'xxxxx', 'from_name':'Test', 'to_name':'', 'template_id':54457, 'inline_css':True, 'generate_text': True, 'title':'testing' }
template_content = {"html_postcard_heading00":"<h1>Testing</h1>","html_std_content00":"<h1>Testing</h1>","html_postcard_image":"<img src='image_path'>"}
and pass this content to
campaignCreate(type='regular',options = template_option,content=template_content)
method.
Campaigns creates properly, but the content still not added into the campaign.
Can please anybody tell me why this happens?
Problem is because of Repeatable section. Repeatable section having different way to add data.
Change the template content as below.
template_content = {'html_repeat_1:0:postcard_heading00':postcard_heading[0],
'html_repeat_1:0:postcard_image': postcard_img,
'html_repeat_1:0:std_content00': std_content[0]}
I done this way and problem gets solved.

How can I get access to a Django Model field verbose name dynamically?

I'd like to have access to one my model field verbose_name.
I can get it by the field indice like this
model._meta._fields()[2].verbose_name
but I need to get it dynamically. Ideally it would be something like this
model._meta._fields()['location_x'].verbose_name
I've looked at a few things but I just can't find it.
For Django < 1.10:
model._meta.get_field_by_name('location_x')[0].verbose_name
model._meta.get_field('location_x').verbose_name
For Django 1.11 and 2.0:
MyModel._meta.get_field('my_field_name').verbose_name
More info in the Django doc
The selected answer gives a proxy object which might look as below.
<django.utils.functional.__proxy__ object at 0x{SomeMemoryLocation}>
If anyone is seeing the same, you can find the string for the verbose name in the title() member function of the proxy object.
model._meta.get_field_by_name(header)[0].verbose_name.title()
A better way to write this would be:
model._meta.get_field(header).verbose_name.title()
where header will be the name of the field you are interested in. i.e., 'location-x' in OPs context.
NOTE: Developers of Django also feel that using get_field is better and thus have depreciated get_field_by_name in Django 1.10. Thus I would suggest using get_field no matter what version of Django you use.
model._meta.get_field_by_name('location_x')[0].verbose_name
You can also use:
Model.location_x.field.verbose_name
Model being the class name. I tested this on my Animal model:
Animal.sale_price.field.verbose_name
Animal.sale_price returns a DeferredAttribute, which has several meta data, like the verbose_name
Note: I'm using Django 3.1.5
If you want to iterate on all the fields you need to get the field:
for f in BotUser._meta.get_fields():
if hasattr(f, 'verbose_name'):
print(f.verbose_name)
# select fields for bulk_update : exclude primary key and relational
fieldsfields_to_update = []
for field_to_update in Model._meta.get_fields():
if not field_to_update.many_to_many and not field_to_update.many_to_one and not field_to_update.one_to_many and not field_to_update.one_to_one and not field_to_update.primary_key and not field_to_update.is_relation :
fields_to_update = fields_to_update + [field_to_update.name]
Model.objects.bulk_update(models_to_update , fields_to_update)