我正在努力通过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教程页面上列出的格式完全匹配
[{'name': u'url', 'value': None, 'foreign_key': [2L]}, {'name': u'pid', 'value': u'43d9f', 'foreign_key': [2L]}]
我试过了:
删除我的数据库并从头开始重新创建
在for循环中移动insert语句,以便一次只有一个插入
发出insert语句为 conn.execute(refQuery.insert(), newDict)
编码我的所有字符串,以便我不混合字符串和unicode
将implicit_returning设置为False以禁用refQuery主键的返回
到目前为止没有任何工作,每次都有相同的错误.有人能指出我正确的方向吗?
注意错误:
'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"放在引号中,因为该列查询的响应是一个"类似列表"或"类似元组"的对象,称为"KeyedTuple",类似于collections.namedtuple
标准库,并允许您访问像result[0]
和的价值result.id