我有一个在 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)
最佳答案
你在 Ubuntu 上的 psycopg2
库太旧了;您需要升级到 2.5 或更高版本。在旧版本中,连接尚不支持用作上下文管理器。
参见 Psycopg 2.5 release announcement :
Connections and cursors as context managers
A recent DBAPI extension has standardized the use of connections and cursors as context managers: it is now possible to use an idiom such as:
with psycopg2.connect(DSN) as conn: with conn.cursor() as curs: curs.execute(SQL)
with the intuitive behaviour: when the cursor block exits the cursor is closed; when the connection block exits normally the current transaction is committed, if it exits with an exception instead the transaction is rolled back, in either case the connection is ready to be used again
如果您安装了 python-psycopg2
system package您最有可能使用 2.4.5;只有 Utopic Unicorn (14.10) 有更新的版本 (2.5.3)。要从源安装较新版本,您需要安装 Python 开发 header (python-dev
) 和 PostgreSQL 客户端库 header (libpq-dev
)。
关于python - "with"语句适用于 Windows 但不适用于 Ubuntu,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26446738/