Closed juanchristian closed 10 years ago
You should call backend.commit()
to save changes.
Yeah this might just be the problem! When using filter or get, BlitzDB will not show you any records that have been saved but not committed to the database.
If you don't want to call commit every time, you can create the backend with the autocommit = True
option, which will automatically commit after every save
or update
call.
Please let us know if this fixed your problem!
Same issue:
import requests from blitzdb import Document, FileBackend
API_URL = 'http://api.themoviedb.org/3' API_KEY = 'ddf3xxxxxxxx0289'
class Actor(Document): pass
def get_actor(_id): r = requests.get('{}/person/{}?api_key={}'.format(API_URL, str(_id), API_KEY)) return r.json()
actor_1 = Actor(get_actor(1)) actor_2 = Actor(get_actor(2))
backend = FileBackend("db.blitz") actor_1.save(backend) actor_2.save(backend) backend.commit()
print(backend.get(Actor,{'imdb_id' : 'nm0000184'})) print('\n') print(backend.get(Actor,{'imdb_id' : 'nm0000434'}))
OUTPUT --------------
Warning: cjson could not be imported, CJsonSerializer will not be available.
Traceback (most recent call last):
File ".\test.py", line 24, in
I ran your code with BlitzDB 0.2.6 and unfortunately I still can't reproduce the issue. My output looks like this:
Actor({'pk' : 'ae214f4e5abb11e480bd2477037d8f1c'},lazy = False)
Actor({'pk' : 'ae21c4c45abb11e480bd2477037d8f1c'},lazy = False)
The JSON output I receive from the API is the following:
{u'name': u'George Lucas', u'popularity': 3.2783625, u'imdb_id': u'nm0000184', u'birthday': u'1944-05-14', u'adult': False, u'place_of_birth': u'Modesto - California - USA', u'deathday': u'', u'profile_path': u'/rJ1zvSeZfge0mHtLnzJn4Mkw18S.jpg', u'homepage': u'', u'id': 1, u'biography': u'Arguably the most important film innovator in the history of the medium, George Lucas continually "pushed the envelope" of filmmaking technology since his early days as a student at U.S.C. Considered a wunderkind by his contemporaries, he had a much harder time communicating his vision to studio executives, whose meddling managed to compromise each of his first three feature directing efforts in some way. The monumental success of "Star Wars" (1977) ushered in the era of the "summer blockbuster," which, despite the later popularity of low budget independent films, was still the prevailing mentality powering the Hollywood engine.\n\nThough he set the tone and established the expectations which influenced studios to devote the bulk of their resources to films designed to blast off into hyperspace for spectacular profits, it was doubtful that a film as revolutionary as "Star Wars" was in its day could get made in the later blockbuster assembly line climate of the new millennium.', u'also_known_as': [u'George Walton Lucas Jr. ']} {u'name': u'Mark Hamill', u'popularity': 11.137056, u'imdb_id': u'nm0000434', u'birthday': u'1951-09-25', u'adult': False, u'place_of_birth': u'Concord, California, USA', u'deathday': u'', u'profile_path': u'/klQrOckrIuUluOEp7g0osOfTgWI.jpg', u'homepage': u'', u'id': 2, u'biography': u'From Wikipedia, the free encyclopedia.\n\nMark Richard Hamill (born September 25, 1951) is an American actor, voice artist, producer, director, and writer. Hamill is best known for his role as Luke Skywalker in the original Star Wars trilogy and also well known for voice-acting characters such as the Joker in various animated series, animated films and video games, beginning with Batman: The Animated Series, the Skeleton king in Super Robot Monkey Team Hyperforce Go!, Fire Lord Ozai in Avatar: The Last Airbender, Master Eraqus in Kingdom Hearts: Birth by Sleep, Skips in Regular Show, and Senator Stampington on Metalocalypse.\n\nDescription above from the Wikipedia article Mark Hamill, licensed under CC-BY-SA, full list of contributors on Wikipedia .', u'also_known_as': []}
The only thing I could advise you to do is to delete the database directory and try again. Also, please make sure that you've installed the latest version of BlitzDB. I'm sorry that I can't provide you better advice.
I also checked with Python 3 and discovered a unicode bug (which is unrelated to your problem though). Please check out BlitzDb v0.2.7.
Working now on v0.2.7 using the same code.
import requests from blitzdb import Document, FileBackend
API_URL = 'http://api.themoviedb.org/3' API_KEY = 'xxxxxxxxxx'
class Actor(Document): pass
def get_actor(_id): r = requests.get('{}/person/{}?api_key={}'.format(API_URL, str(_id), API_KEY)) return r.json()
actor_1 = Actor(get_actor(1)) actor_2 = Actor(get_actor(2))
backend = FileBackend("db.blitz") actor_1.save(backend) actor_2.save(backend) backend.commit()
print(backend.get(Actor, {'imdb_id': 'nm0000184'})) print(backend.get(Actor, {'imdb_id': 'nm0000434'}))
Actor({'pk' : 'd64d37645ae611e49c00a417310f9aa6'},lazy = False) Actor({'pk' : 'd64d37655ae611e4bd84a417310f9aa6'},lazy = False)
PS: Is there a way to implement something like:
var = Actor(ID_GOES_HERE)
and have the class Actor
calling the API using requests.get()
instead of a function get_actor
for that?
I tried:
def __init__(self, id):
super(requests.get(
'{}/person/{}?api_key={}'.format(API_URL, str(id), API_KEY)).json())`
But, didn't work.
Great, happy that it works now!
You could possibly accomplish this with the initialize
function:
http://blitzdb.readthedocs.org/en/latest/api/document.html#blitzdb.document.Document.initialize
It's also possible to define a pre_save
function in the class, which will get called before a document gets saved, and where you could e.g. call the API and update the movie information if it's not yet contained in the document. Let me know if that works for you!
I think I didn't get what you said, let's say I have this:
import requests from blitzdb import Document, FileBackend
class TMDB:
def __init__(self, key):
self._API_KEY = key
self._API_URL = 'http://api.themoviedb.org/3/'
def get_id(self, query_type, query):
query = str(query).replace(' ', '%20')
response = requests.get(self._API_URL
+ 'search/' + query_type
+ '?api_key=' + self._API_KEY
+ '&query=' + query).json()
if response['total_results'] == 0:
raise
return response['results'][0]['id']
def get_object(self, query_type, id):
return requests.get(self._API_URL + query_type + '/' + id + '?api_key=' + self._API_KEY).json()
API = TMDB('xxxxxxxxxxxx') backend = FileBackend("db.blitz")
class Actor(Document):
def __init__(self, id):
actor = API.get_object('person', 287)
actor.save(backend)
backend.commit()
I need to implement this thing on the init of Actor so I can call it like var = Actor(123)
and inside the same func this would save and commit to the db. I know that this approach isn't quit good for this kind of work, but I just want to play with blitzdb in order to learn it better!
Hey @jcchristian sorry for the super-late answer! You could do it like this, but if you overwrite the init function make sure to support the right signature and call the original init of the superclass (e.g. via super(Actor,self).__init__(...)
.
As I said above, initialize
will get called whenever the object receives it's values from the database, so you could just overwrite it to check if your data is there, and if not go and get it from the database. Like so:
class Actor(Document):
def initialize(self):
if not 'is_loaded' in self:
#fetch your data from the DB here...
self.is_loaded = True
Does that solve your problem?
Many thanks, I'l close here now. :+1:
Testing code:
CODE ---------------------
!/usr/bin/env
import requests from blitzdb import Document, FileBackend
API_URL = 'http://api.themoviedb.org/3' API_KEY = 'ddf3xxxxxxxx0289'
class Actor(Document): pass
def get_actor(_id): r = requests.get('{}/person/{}?api_key={}'.format(API_URL, str(_id), API_KEY)) return r.json()
actor_1 = Actor(get_actor(1)) actor_2 = Actor(get_actor(2))
backend = FileBackend("db.blitz") actor_1.save(backend) actor_2.save(backend)
print(backend.get(Actor,{'imdb_id' : 'nm0000184'})) print('\n') print(backend.get(Actor,{'imdb_id' : 'nm0000434'}))
OUTPUT ---------------------
Warning: cjson could not be imported, CJsonSerializer will not be available. Traceback (most recent call last): File ".\uff.py", line 27, in
print(backend.get(Actor,{'imdb_id' : 'nm0000184'}))
File "C:\Python34\lib\site-packages\blitzdb\backends\file\backend.py", line 456, in get
raise cls.DoesNotExist
blitzdb.document.DoesNotExist: DoesNotExist(Actor)
QUESTION ---------------------
Why the output says that Actor doesn't exists when I already added it here 'actor_1.save(backend)' and 'actor_2.save(backend)'
Oh yes, and here is what the call to the API returns:
{"adult":false,"also_known_as":["George Walton Lucas Jr. "],"biography":"Arguably the most important film innovator in the history of the medium, George Lucas continually \"pushed the envelope\" of filmmaking technology since his early days as a student at U.S.C. Considered a wunderkind by his contemporaries, he had a much harder time communicating his vision to studio executives, whose meddling managed to compromise each of his first three feature directing efforts in some way. The monumental success of \"Star Wars\" (1977) ushered in the era of the \"summer blockbuster,\" which, despite the later popularity of low budget independent films, was still the prevailing mentality powering the Hollywood engine.\n\nThough he set the tone and established the expectations which influenced studios to devote the bulk of their resources to films designed to blast off into hyperspace for spectacular profits, it was doubtful that a film as revolutionary as \"Star Wars\" was in its day could get made in the later blockbuster assembly line climate of the new millennium.","birthday":"1944-05-14","deathday":"","homepage":"","id":1,"imdb_id":"nm0000184","name":"George Lucas","place_of_birth":"Modesto - California - USA","popularity":2.185575,"profile_path":"/rJ1zvSeZfge0mHtLnzJn4Mkw18S.jpg"}