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

时间:2021-10-03 12:17:55

I'm struggling with inserting one-to-many relationship in SQL Server via SQLAlchemy. I'm getting an Invalid parameter type error no matter what I try.

我正在努力通过SQLAlchemy在SQL服务器中插入一对多关系。无论如何,我都会得到一个无效的参数类型错误。

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)

When I run this code, everything works correctly until the second insert. This means that my first insert statement logInsert works. Here's the data that's input to that statement:

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

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

And here's what the logInsert statement looks like:

下面是logInsert语句的样子:

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

My second insert, conn.execute(ins) gives the following error:

我的第二个插入,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])

I've printed out the newDict, and its format exactly matches what's listed on the SQLAlchemy Tutorial Page

我已经打印出了newDict,它的格式与SQLAlchemy教程页面上列出的内容完全匹配。

[{'name': u'url', 'value': None,     'foreign_key': [2L]}, 
 {'name': u'pid', 'value': u'43d9f', 'foreign_key': [2L]}]

I've tried:

我试过了:

  • deleting my database & recreating from scratch
  • 删除我的数据库并重新创建
  • moving the insert statement inside the for-loop so that there's only one insert at a time
  • 将insert语句移动到for循环中,以便每次只有一个insert
  • issuing the insert statement as conn.execute(refQuery.insert(), newDict)
  • 以conn.execute(refQuery.insert()、newDict类型)的形式发出insert语句
  • encoding all of my strings so that I'm not mixing strings & unicode
  • 编码所有的字符串,这样就不会混合字符串和unicode了
  • set implicit_returning to False to disable the return of of the refQuery primary key
  • 将implicit_return设置为False,以禁用refQuery主键的返回

Nothing has worked so far, same error each time. Can someone point me in the right direction?

到目前为止,一切都没有进展,每次都是同样的错误。有人能给我指出正确的方向吗?

1 个解决方案

#1


5  

Notice the error:

注意到错误:

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

And then the values you're putting in on param-index 2:

然后你在参数指数2中输入的值:

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

You're submitting a list, instead of single value.

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

Your problem is this line:

你的问题是:

ins_id = result.inserted_primary_key

according to the docs

根据文档

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

Return the primary key for the row just inserted. The return value is a list of scalar values corresponding to the list of primary key columns in the target table."

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

So you want:

所以你想要的:

ins_id = result.inserted_primary_key[0]

Watch out for the term "scalar value" in the docs. SqlAlchemy often returns a "list" when you might expect otherwise. For example: if you select a single column, like session.query(Model.id).filter(id==1).first(), your result will be (1, ), not 1.

注意文档中的术语“标量值”。SqlAlchemy通常会返回一个“列表”,而您可能会有其他的期望。例如:如果您选择一个列,如session.query(Model.id).filter(id= 1).first(),您的结果将是(1,),而不是1。

I put "list" in quotes, because the response on that column query is a "list-like" or "tuple-like" object called a "KeyedTuple" that is similar to the collections.namedtuple from teh standard library, and allows you to access the value like result[0] and result.id

我将“list”放在引号中,因为该列查询的响应是一个“类列表”或“类tuple”对象,名为“KeyedTuple”,类似于集合.namedtuple,来自teh标准库,允许您访问结果[0]和result.id之类的值

#1


5  

Notice the error:

注意到错误:

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

And then the values you're putting in on param-index 2:

然后你在参数指数2中输入的值:

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

You're submitting a list, instead of single value.

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

Your problem is this line:

你的问题是:

ins_id = result.inserted_primary_key

according to the docs

根据文档

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

Return the primary key for the row just inserted. The return value is a list of scalar values corresponding to the list of primary key columns in the target table."

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

So you want:

所以你想要的:

ins_id = result.inserted_primary_key[0]

Watch out for the term "scalar value" in the docs. SqlAlchemy often returns a "list" when you might expect otherwise. For example: if you select a single column, like session.query(Model.id).filter(id==1).first(), your result will be (1, ), not 1.

注意文档中的术语“标量值”。SqlAlchemy通常会返回一个“列表”,而您可能会有其他的期望。例如:如果您选择一个列,如session.query(Model.id).filter(id= 1).first(),您的结果将是(1,),而不是1。

I put "list" in quotes, because the response on that column query is a "list-like" or "tuple-like" object called a "KeyedTuple" that is similar to the collections.namedtuple from teh standard library, and allows you to access the value like result[0] and result.id

我将“list”放在引号中,因为该列查询的响应是一个“类列表”或“类tuple”对象,名为“KeyedTuple”,类似于集合.namedtuple,来自teh标准库,允许您访问结果[0]和result.id之类的值