ravenDB + python not saving - python

I'm currently editing existing documents in my ravenDB instance.
The main issue i'm facing is that i get no errors but no changes are saved.
I'm using the following code :
#in init method
self.store = document_store.documentstore(url=self.dbURL, database=self.dbInUse)
self.store.initialize()
def someMethodToSaveData(self, id, newTextField="")
with self.store.open_session() as session:
doc = session.load(id)
doc.newTextField=newTextField
session.store(doc,id)
session.save_changes()
thanks
edit: added session.save_changes() in this code. testing, but i have that line in another project and I'm facing the same issue with it.

I think you will have to call the method session.save_changes() so that the the database transaction completes:
#in init method
self.store = document_store.documentstore(url=self.dbURL, database=self.dbInUse)
self.store.initialize()
def someMethodToSaveData(self, id, newTextField="")
with self.store.open_session() as session:
doc = session.load(id)
doc.newTextField=newTextField
session.store(doc,id)
session.save_changes() # this call is important
I found this information in the offical RavenDB documentation:

Related

Create activities for an user with Stream-Framework

I'm trying to setup stream-framework the one here not the newer getstream. I've setup the Redis server and the environment properly, the issue I'm facing is in creating the activities for a user.
I've been trying to create activities, following the documentation to add an activity but it gives me an error message as follows:
...
File "/Users/.../stream_framework/activity.py", line 110, in serialization_id
if self.object_id >= 10 ** 10 or self.verb.id >= 10 ** 3:
AttributeError: 'int' object has no attribute 'id'
Here is the code
from stream_framework.activity import Activity
from stream_framework.feeds.redis import RedisFeed
class PinFeed(RedisFeed):
key_format = 'feed:normal:%(user_id)s'
class UserPinFeed(PinFeed):
key_format = 'feed:user:%(user_id)s'
feed = UserPinFeed(13)
print(feed)
activity = Activity(
actor=13, # Thierry's user id
verb=1, # The id associated with the Pin verb
object=1, # The id of the newly created Pin object
)
feed.add(activity) # Error at this line
I think there is something missing in the documentation or maybe I'm doing something wrong. I'll be very grateful if anyone helps me get the stream framework working properly.
The documentation is inconsistent. The verb you pass to the activity should be (an instance of?*) a subclass of stream_framework.verbs.base.Verb. Check out this documentation page on custom verbs and the tests for this class.
The following should fix the error you posted:
from stream_framework.activity import Activity
from stream_framework.feeds.redis import RedisFeed
from stream_framework.verbs import register
from stream_framework.verbs.base import Verb
class PinFeed(RedisFeed):
key_format = 'feed:normal:%(user_id)s'
class UserPinFeed(PinFeed):
key_format = 'feed:user:%(user_id)s'
class Pin(Verb):
id = 5
infinitive = 'pin'
past_tense = 'pinned'
register(Pin)
feed = UserPinFeed(13)
activity = Activity(
actor=13,
verb=Pin,
object=1,
)
feed.add(activity)
I quickly looked over the code for Activity and it looks like passing ints for actor and object should work. However, it is possible that these parameters are also outdated in the documentation.
* The tests pass in classes as verb. However, the Verb base class has the methods serialize and __str__ that can only be meaningfully invoked if you have an object of this class. So I'm still unsure which is required here. It seems like in the current state, the framework never calls these methods, so classes still work, but I feel like the author originally intended to pass instances.
With the help of great answer by #He3lixxx, I was able to solve it partially. As the package is no more maintained, the package installs the latest Redis client for python which was creating too many issues so by installation redis-2.10.5 if using stream-framework-1.3.7, should fix the issue.
I would also like to add a complete guide to properly add activity to a user feed.
Key points:
If you are not using feed manager, then make sure to first insert the activity before you add it to the user with feed.insert_activity(activity) method.
In case of getting feeds with feed[:] throws an error something like below:
File "/Users/.../stream_framework/activity.py", line 44, in get_hydrated
activity = activities[int(self.serialization_id)]
KeyError: 16223026351730000000001005L
then you need to clear data for that user using the key format for it in my case the key is feed:user:13 for user 13, delete it with DEL feed:user:13, In case if that doesn't fix the issue then you can FLUSHALL which will delete everything from Redis.
Sample code:
from stream_framework.activity import Activity
from stream_framework.feeds.redis import RedisFeed
from stream_framework.verbs import register
from stream_framework.verbs.base import Verb
class PinFeed(RedisFeed):
key_format = 'feed:normal:%(user_id)s'
class UserPinFeed(PinFeed):
key_format = 'feed:user:%(user_id)s'
class Pin(Verb):
id = 5
infinitive = 'pin'
past_tense = 'pinned'
register(Pin)
feed = UserPinFeed(13)
print(feed[:])
activity = Activity(
actor=13,
verb=Pin,
object=1)
feed.insert_activity(activity)
activity_id = feed.add(activity)
print(activity_id)
print(feed[:])

Overwriting a method from another module

I am working with jira-python and want to overwrite the existing method Issue.update() method. However, my code is never calling the modification.
from jira import JIRA
from jira.resources import Issue
class Issue(Issue):
def update(self):
print("overwritten")
super(Issue, self).update() # I also tried super().update()
jira = JIRA("...") # holds a reference to the JIRA instance
issues = jira.search_issues("") # holds a list of JIRA Issues
for issue in issues:
// I would expect this call to print "overwritten"
issue.update()
You can monkey-patch the method with a wrapper like this:
from jira.resources import Issue
def my_update(self):
print('overwritten')
original_update(self)
original_update = Issue.update
Issue.update = my_update

class variable was caches in next request when use django-rest-framework renderer

I make use of uwsgi, django and django-rest-framework to develop one application.
I introduced one class variable in renderer class, this variable will be fill as one part of response.
the problem seems likes as following:
class xxxRenderer(xxxBase)
response_pb_msg = obj # it's one instance of protobuf message
def render():
if True:
self.response_pb_msg.items = []
else:
self.response_pb_msg.retCode = 100
self.response_pb_msg.otherXXXX = xxxx
In django logger handler, I access this class variable again like following:
xxxRenderer.response_pb_msg.ParseFromString(body)
after the first response, this class variable 'response_pb_msg' only has one property "retCode"
but the second response, it has three properties "retCode", "otherXXXX " and "items "
it's strange, the second response contain all content which was exist in the first response.
after a time, I re-wrote this class like following:
class xxxBaserender(xxRender)
def __init__():
if self.response_pb_msg_cls is not None and isinstance(self.response_pb_msg_cls, GeneratedProtocolMessageType):
self.response_pb_message = self.response_pb_msg_cls()
class xxxRenderer(xxxBaserender)
response_pb_msg_cls = msgName # the class of protobuf message
theoretically, the second class is ok. I tested, didn't duplicate that question.
Let's return to where we started
Every request finisehd, all resoure should be clean.
but I'm very puzzled with that problem, it seems that class variable not been released in uwsgi progress after response return.
I read “PEP 3333”, didn't get any valuable information.
I think I didn't fully understand class variaable, wsgi and web processing flow in python.
anyone can help me to understand this problem?
thanks vey much.

Understanding Class inheritance to DRY up some code

I am using the cloudant python library to connect to my cloudant account.
Here is the code I have so far:
import cloudant
class WorkflowsCloudant(cloudant.Account):
def __init__(self):
super(WorkflowsCloudant, self).__init__(settings.COUCH_DB_ACCOUNT_NAME,
auth=(settings.COUCH_PUBLIC_KEY,
settings.COUCH_PRIVATE_KEY))
#blueprint.route('/<workflow_id>')
def get_single_workflow(account_id, workflow_id):
account = WorkflowsCloudant()
db = account.database(settings.COUCH_DB_NAME)
doc = db.document(workflow_id)
resp = doc.get().json()
if resp['account_id'] != account_id:
return error_helpers.forbidden('Invalid Account')
return jsonify(resp)
This Flask controller will have CRUD operations inside of it, but with the current implementation, I will have to set the account and db variables in each method before performing operations on the document I want to view/manipulate. How can I clean up (or DRY up) my code so that I only have to call to my main WorkflowsCloudant class?
I don't know cloudant, so I may be totally off base, but I believe this answers your question:
Delete the account, db, and doc lines from get_single_workflow.
Add the following lines to __init__:
db = account.database(settings.COUCH_DB_NAME)
self.doc = db.document(workflow_id)
Change the resp line in get_single_workflow to:
resp = WorkflowsCloudant().doc.get().json()

Why do I getting 'FileField' object has no attribute 'put'?

Following http://mongoengine.org/docs/v0.4/guide/gridfs.html documentation about mongoengine FileField I did the following:
In my model
files = ListField(FileField())
In my test code
# Create an entry
photo = FileField()
f = open('/home/foo/marmot.jpg', 'r')
photo.put(f, content_type='image/jpeg')
entry.files = [photo,]
Trying to follow the doc, however i get an error:
Traceback (most recent call last):
File "/home/bar/tests.py", line 76, in test_MongoDGACLogook_creation
photo.put(f, content_type='image/jpeg')
AttributeError: 'FileField' object has no attribute 'put'
Am I missing something obvious ?
Thanks
This isn't obvious at all IMO, but if you look at the Mongoengine code you'll see that the put method is defined in the GridFSProxy class, which is accessed via a descriptor in FileField (the __get__ and __set__ methods).
Looking at the code and the examples in the docs, it appears the only way to access or use a FileField is through the descriptor....so, collection.file_field.
Given all this, I don't think it's possible to have a list of file fields using the Mongoengine API as it exists now.
f = mongoengine.fields.GridFSProxy()
to_read = open('/home/.../marmot.jpg', 'r')
f.put(to_read, filename=os.path.basename(to_read.name))
to_read.close()
If you are uploading multiples files and trying to save it a ListField(FileField())
<input type='file' name='myfiles' multiple="">
files = []
for f in request.FILES.getlist('myfiles'):
mf = mongoengine.fields.GridFSProxy()
mf.put(f, filename=f.name)
files.append(mf)
entry.files = files
entry.save()
I had exactly the same problem. As suggested by #KoppeKTop on GitHub in this post, I finally extended my model (Pet) using an EmbeddedDocument like this:
class OneImage(mongoengine.EmbeddedDocument):
element = ImageField()
class Pet(mongoengine.Document):
photos = EmbeddedDocumentListField(OneImage)
# ...more fields... #
I can then add a new image using
i = OneImage()
i.element.put(form.photo.data.stream)
entry.photos.append(i)
entry.save()
This may not always be the best option, but personally I prefer it because I can work with models as usual without having to work with proxies. And I can also save other photo metadata in the future, if I need to.

Categories

Resources