python - "with"语句适用于 Windows 但不适用于 Ubuntu

标签 python windows postgresql ubuntu with-statement

我有一个在 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/

相关文章:

python - 如何仅使用普通 python 激活 google colab gpu

python - 仅使用加法和减法求两个数的乘积?

c - 在 Windows C 中获取与真实硬件以太网 Controller 关联的 IP 地址

python - 如何使用 Python 测试 timescaledb 数据库

python - 如何使 Pelican 开发服务器传送不带扩展名的文件?

python - 保留作为序列一部分的数组的第一个元素

c++ - 产品/消费者——什么是最佳信号模式

c - 如何创建未定义数量的线程并在 Windows 上的 c 中使用 WaitForMultipleObjects()

node.js - 锁定 postgres 事务

postgresql - "GRANT SELECT table TO role"不工作