tags:

views:

152

answers:

3

Hello, I want to keep last.fm's user recent music tracks list to postgresql database table using pylast interface.But when I tried to insert values to the table it shows errors.Code example:

import pylast
import psycopg2
import re
from md5 import md5
import sys
import codecs
import psycopg2.extensions

psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
user_name = raw_input("Enter last.fm username: ")
user_password = raw_input("Enter last.fm password: ")

api_key = '*********'
api_secret = '********'

#Lastfm network authentication
md5_user_password = md5(user_password).hexdigest()
network = pylast.get_lastfm_network(api_key, api_secret,user_name,md5_user_password)

used=pylast.User(user_name, network)

recent_tracks=used.get_recent_tracks(10)

# Database connection 
try:
    conn=psycopg2.connect("dbname='**' user='postgres' host='localhost'   password='*'")
    conn.set_client_encoding('UNICODE')
except:
    print "I am unable to connect to the database, exiting."
    sys.exit()
cur=conn.cursor()

for i, artist in enumerate(recent_tracks):
    for key in sorted(artist):

        cur.execute("""
        INSERT INTO u_recent_track(Playback_date,Time_stamp,Track) 
        VALUES (%s,%s,%s)""",  (key, artist[key]))

    conn.commit()
cur.execute("SELECT * FROM u_recent_track;")
cur.fetchone()
for row in cur:
    print '   '.join(row[1:])

cur.close()
conn.close()

Here "recent_tracks" tuple have the values for example:

artist 0
  - playback_date : 5 May 2010, 11:14
  - timestamp : 1273058099
  - track         : Brian Eno - Web

I want to store these value under u_recent_track(Tid,Playback_date,Time_stamp,Track).Can anybody have idea how to sort out this problem? when I tried to run, it shows error:

Traceback (most recent call last):
  File "F:\JavaWorkspace\Test\src\recent_track_database.py", line 50, in <module>
    VALUES (%s,%s,%s)""",  (key, artist[key]))
IndexError: tuple index out of range

Thanks in advanced!

A: 

(Playback_date,Time_stamp,Track) indicates you want to insert three values into a row. VALUES (%s,%s) should therefore be VALUES (%s,%s,%s) and (key, artist[key]) should be a tuple with 3 elements, not 2.

Try:

for track in recent_tracks:
    cur.execute("""
        INSERT INTO u_recent_track(Playback_date,Time_stamp,Track) 
        VALUES (%s,%s,%s)""",  (track.get_date(), track.get_timestamp(), track.get_track()))
    conn.commit()

PS. This is where I'm getting my information about the pylast API.

PPS. If my reading of the documentation is correct, track.get_track() will return a Track object. It has methods like get_album, get_artist, get_id and get_title. Exactly what do you want stored in the Track column of the u_recent_track database table?

unutbu
Well, you are right, I have edited the Values (%s, %s , %s)..!..
rahman.bd
@unutbu: recent-tracks are from pylast user class!..it cant help more! :(
rahman.bd
+1  A: 

sorted(artist) returns a ordered list of artist, when you're iterating over it it returns still elements of artist. So when you're trying to access artist[key] it is actually trying to access an element of artist indexed by the index, which is an element of artist itself. Tuples do not work this way.

It seems you're using python2.5 or lower and therefore you could do:

cur.executemany("""
        INSERT INTO u_recent_track(Playback_date,Time_stamp,Track) 
        VALUES (%(playback_date)s,%(timestamp)s,%(track)s)""",  recent_tracks)
conn.commit()

This should work.

SilentGhost
I have tried with that, but it reports like:AttributeError: 'dict' object has no attribute 'playback_date'but it has, I cant get that point :(
rahman.bd
@rahman: use `dir(track)` to see what's inside the `track` variable.
SilentGhost
@SilentGhost:in track variable, using dir , I get :['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__str__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
rahman.bd
@rahman: what version of pylast are you using?
SilentGhost
@silentghost: I am using pylast-0.4.20 !
rahman.bd
@rahman: updated
SilentGhost
@silentghost: still error on :psycopg2.ProgrammingError: can't adapt
rahman.bd
@rahman: look, each of the packages you're using either has excelent documentation or is written in plain python. you could also see what is required as an input with `help(cur.execute)` command. Docs for psycopg2 are here http://initd.org/psycopg/docs/ with examples, etc.
SilentGhost
@silentghost: I was trying on this matter!..It doesn't help..!could you please look it back again?
rahman.bd
@rahman: you need to establish what is actually not working and what is contained in `recent_tracks`. I'll fix typo in a sec.
SilentGhost
"recent_tracks" is list variable.Which can hold track informationlike playback_date , timestamp and track info from pylast interface.you can look from below segment:"used=pylast.User(user_name, network)recent_tracks=used.get_recent_tracks(10)"And now I cant get those user information about track in database table I have shown in the code! it shows "psycopg2.ProgrammingError: can't adapt" after editing my code suggested by you! It is badly needed to resolve :(
rahman.bd
@silentghost: I have another script relating to get recent_tracks which is working to user information, out put sample is like :artist 0 - playback_date : 5 May 2010, 11:14 - timestamp : 1273058099 - track : Brian Eno - Web So I want to keep these information in a table and retrieve from that.Thats why I made the above code script to do that..!
rahman.bd
@rahman: can you get anything into that table? I fixed that typo. It should work now.
SilentGhost
@Silentghost: Unfortunately not! What typo you fixed? was it timestampe to timestap! same error!..
rahman.bd
@silentghost : could you please look that again as it seems it doesn't insert user track data to the database table yet :(
rahman.bd
@rahman: create a simple working test, that would insert a record using `cursor.execute` and the query I've provided. `recent_tracks` should be a simple dictionary with three elements. If that doesn't work, then your problem lies elsewhere.
SilentGhost
A: 

This error isn't anything to do with Postgres, but with the artist variable. You're firstly saying:

for key in sorted(artist):

implying that it's a list, but then you're accessing it as if it were a dictionary, which is raising an error. Which is it? Can you show an example of the full contents?

Daniel Roseman
Well, I have edited my code with full contents.can you please look whats the heck here ? Thanks in advanced!
rahman.bd