SQLAlchemy中的无效参数类型错误在SQL Server中插入

时间:2014-11-12 23:31:27

标签: python sql-server insert sqlalchemy

我正在努力通过SQLAlchemy在SQL Server中插入一对多关系。无论我尝试什么,我都会收到Invalid parameter type错误。

import pyodbc
from sqlalchemy import BigInteger, Column, create_engine, ForeignKey, String,
 MetaData, Table

meta = MetaData()

logFile = Table('logFile', meta,
    Column('id', BigInteger, primary_key=True),
    Column('referrer_anchor', String(900), nullable=True),
    Column('referrer_hostname', String(900), nullable=True),
    Column('referrer_path', String(900), nullable=True))

refQuery = Table('refQuery', meta,
    Column('rQ_id', BigInteger, primary_key=True),
    Column('name', String(8000)),
    Column('value', String(8000)),
    Column('foreign_key', None, ForeignKey('logFile.id'), nullable=False))

engine = create_engine(...)
conn = engine.connect()

# create dictionary
logKeys = ['referrer_anchor', 'referrer_hostname', 'referrer_path']
logVals = [myRefAnchor, myRefHost, myRefPath]
logDict = dict(zip(logKeys, logVals))

# insert
logInsert = logFile.insert().values(logDict)
result = conn.execute(logInsert)
ins_id = result.inserted_primary_key

if refQueryPairs:
    newDict = []
    names = ['name', 'value', 'foreign_key']
    for k, v in refQueryPairs.items():
        vals = [k, v, ins_id]
        tempDict = dict(zip(names, vals))
        newDict.append(tempDict)
    ins = refQuery.insert().values(newDict)
    conn.execute(ins)

当我运行此代码时,一切正常,直到第二次插入。这意味着我的第一个插入语句logInsert有效。这是输入该语句的数据:

{'referrer_anchor': '"site.com"', 'referrer_hostname': '"site.com"', 'referrer_path':
 '"/clothing/mens/shoes/6114"'}

以下是logInsert语句的内容:

INSERT INTO activate (referrer_anchor, referrer_hostname, referrer_path) VALUES 
(:referrer_anchor, :referrer_hostname, :referrer_path)

我的第二个插入内容conn.execute(ins)出现以下错误:

sqlalchemy.exc.ProgrammingError: (ProgrammingError) ('Invalid parameter type.  param-
index=2 param-type=list', 'HY105') u'INSERT INTO refQuery (name, value, foreign_key) 
OUTPUT inserted.[rQ_id] VALUES (?, ?, ?), (?, ?, ?)' (u'url', None, [2L], u'pid', u'4
3d9f', [2L])

我已打印出newDict,其格式与SQLAlchemy Tutorial Page

上列出的内容完全匹配
[{'name': u'url', 'value': None,     'foreign_key': [2L]}, 
 {'name': u'pid', 'value': u'43d9f', 'foreign_key': [2L]}]

我试过了:

  • 删除我的数据库&从头开始重建
  • 在for-loop中移动insert语句,以便一次只能插入一个
  • conn.execute(refQuery.insert(), newDict)
  • 发出insert语句
  • 对我的所有字符串进行编码,这样我就不会混合字符串&的unicode
  • 将implicit_returning设置为False以禁用refQuery主键的返回

到目前为止,没有任何工作,每次都有相同的错误。有人能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:5)

请注意错误:

 'Invalid parameter type.  param-index=2 param-type=list

然后你在param-index 2上输入的值:

(u'url', None, [2L]

您提交的是列表,而不是单个值。

你的问题就在这一行:

ins_id = result.inserted_primary_key

根据文档

http://docs.sqlalchemy.org/en/latest/core/connections.html?highlight=inserted_primary_key#sqlalchemy.engine.ResultProxy.inserted_primary_key
  

返回刚刚插入的行的主键。   返回值是与目标表中主键列列表对应的标量值列表。"

所以你想要:

ins_id = result.inserted_primary_key[0]

注意术语"标量值"在文档中。 SqlAlchemy经常返回一个"列表"当你不期望的时候。例如:如果您选择单个列,例如session.query(Model.id).filter(id==1).first(),则结果将为(1, ),而不是1

我把" list"在引号中,因为该列查询的响应是"类似列表的"或" tuple-like"对象称为" KeyedTuple"与标准库中的collections.namedtuple类似,并允许您访问result[0]result.id

等值