在Python中向PostgreSQL表插入元组值时出错

0 投票
3 回答
1916 浏览
提问于 2025-04-15 22:25

我想把last.fm用户最近听的音乐曲目列表保存到PostgreSQL数据库的表里,使用的是pylast这个接口。但是当我尝试把数据插入到表里时,出现了错误。代码示例如下:

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()

这里的“recent_tracks”元组包含了一些值,比如:

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

我想把这些值存储在u_recent_track这个表里,字段包括Tid、Playback_date、Time_stamp和Track。有没有人知道怎么解决这个问题?我在运行的时候,出现了错误:

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

3 个回答

0

(Playback_date,Time_stamp,Track) 表示你想在一行中插入三个值。VALUES (%s,%s) 因此应该改成 VALUES (%s,%s,%s),而 (key, artist[key]) 应该是一个包含三个元素的元组,而不是两个。

试试这个:

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()

顺便说一下,我获取关于 pylast API 的信息就是在这里

另外,如果我对文档的理解没错的话,track.get_track() 会返回一个 Track 对象。这个对象有一些方法,比如 get_albumget_artistget_idget_title。你到底想在 u_recent_track 数据库表的 Track 列中存储什么呢?

0

这个错误跟Postgres没有关系,而是和artist这个变量有关。你一开始是说:

for key in sorted(artist):

这意味着它是一个列表,但接着你又把它当成字典来访问,这就导致了错误。那么到底是哪个呢?你能给个完整的例子吗?

1

sorted(artist) 会返回一个有序的艺术家列表,当你遍历这个列表时,它仍然会返回 artist 中的元素。所以,当你尝试访问 artist[key] 时,其实是在根据索引访问 artist 中的一个元素,而这个索引本身也是 artist 中的一个元素。元组并不是这样工作的。

看起来你在使用 Python 2.5 或更早的版本,因此你可以这样做:

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

这样应该可以正常工作。

撰写回答