我有一个脚本(见下文),它在Windows中完美运行,我正在尝试迁移到Ubuntu环境。我已经设置了完全相同的PostgreSQL数据库,具有完全相同的表和用户名等。但是,当我尝试在Ubunu中运行脚本时,它在解析“with”语句时失败。
以下是“with”声明:
with con:
cur = con.cursor()
cur.executemany(final_str, symbols)
我收到以下错误:
INSERT INTO symbol (ticker, instrument, name, sector, currency, created_date, last_updated_date) VALUES (%s, %s, %s, %s, %s, %s, %s) 502
Traceback (most recent call last):
File "loadSPX.py", line 60, in <module>
insert_snp500_symbols(symbols)
File "loadSPX.py", line 54, in insert_snp500_symbols
with con:
AttributeError: __exit__
但是,如果我删除“with”并将其更改为以下内容,则可以完美地运行:
cur = con.cursor()
cur.executemany(final_str, symbols)
con.commit()
任何想法导致了什么?以下是完整的脚本:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import datetime
import lxml.html
import psycopg2 as mdb
import psycopg2.extras
from math import ceil
def obtain_parse_wiki_snp500():
"""Download and parse the Wikipedia list of S&P500
constituents using requests and libxml.
Returns a list of tuples for to add to database."""
# Stores the current time, for the created_at record
now = datetime.datetime.utcnow()
# Use libxml to download the list of S&P500 companies and obtain the symbol table
page = lxml.html.parse('http://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
symbolslist = page.xpath('//table[1]/tr')[1:503]
# Obtain the symbol information for each row in the S&P500 constituent table
symbols = []
for symbol in symbolslist:
tds = symbol.getchildren()
sd = {'ticker': tds[0].getchildren()[0].text,
'name': tds[1].getchildren()[0].text,
'sector': tds[3].text}
# Create a tuple (for the DB format) and append to the grand list
symbols.append( (sd['ticker'], 'stock', sd['name'],
sd['sector'], 'USD', now, now) )
return symbols
def insert_snp500_symbols(symbols):
"""Insert the S&P500 symbols into the database."""
# Connect to the PostgreSQL instance
db_host = 'localhost'
db_user = 'sec_user'
db_pass = 'XXXXXXX'
db_name = 'securities_master'
con = mdb.connect(host=db_host, dbname=db_name, user=db_user, password=db_pass)
# Create the insert strings
column_str = "ticker, instrument, name, sector, currency, created_date, last_updated_date"
insert_str = ("%s, " * 7)[:-2]
final_str = "INSERT INTO symbol (%s) VALUES (%s)" % (column_str, insert_str)
print final_str, len(symbols)
# Using the MySQL connection, carry out an INSERT INTO for every symbol
with con:
cur = con.cursor()
cur.executemany(final_str, symbols)
if __name__ == "__main__":
symbols = obtain_parse_wiki_snp500()
insert_snp500_symbols(symbols)
答案 0 :(得分:6)
你在Ubuntu上的psycopg2
图书馆太旧了;您需要升级到2.5或更高版本。在旧版本中,连接尚不支持用作上下文管理器。
请参阅Psycopg 2.5 release announcement:
连接和游标作为上下文管理器
最近的DBAPI扩展已将连接和游标的使用标准化为上下文管理器:现在可以使用如下的习惯用法:
with psycopg2.connect(DSN) as conn: with conn.cursor() as curs: curs.execute(SQL)
具有直观行为:当光标块退出时光标关闭;当连接块正常退出时,当前事务被提交,如果它以异常退出而不是事务被回滚,则在任何一种情况下连接都可以再次使用
如果您安装了python-psycopg2
system package,则最有可能使用2.4.5;只有Utopic Unicorn(14.10)有更新的版本(2.5.3)。要从soure安装较新版本,您需要安装Python开发标头(python-dev
)以及PostgreSQL客户端库标头(libpq-dev
)。