Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用SQLAlchemy更新PostgreSQL数组_Python_Postgresql_Sqlalchemy - Fatal编程技术网

Python 使用SQLAlchemy更新PostgreSQL数组

Python 使用SQLAlchemy更新PostgreSQL数组,python,postgresql,sqlalchemy,Python,Postgresql,Sqlalchemy,我正在尝试使用SQLAlchemy Core中的SQL语句更新PostgreSQL表上的整数数组。我第一次尝试使用查询生成器,但也不知道如何使用。我相信Psycopg2,我正在使用的方言,可以自动将数组形成PostgreSQL可以接受的格式 以下是表架构: CREATE TABLE surveys ( survey_id serial PRIMARY KEY, question_ids_ordered INTEGER[], created_at TIMESTAMP NOT

我正在尝试使用SQLAlchemy Core中的SQL语句更新PostgreSQL表上的整数数组。我第一次尝试使用查询生成器,但也不知道如何使用。我相信Psycopg2,我正在使用的方言,可以自动将数组形成PostgreSQL可以接受的格式

以下是表架构:

CREATE TABLE surveys (
    survey_id serial PRIMARY KEY,
    question_ids_ordered INTEGER[],
    created_at TIMESTAMP NOT NULL DEFAULT now(),
);
以及SQLAlchemy声明:

survey_id = 46
question_ids_ordered = [237, 238, 239, 240, 241, 242, 243]

with engine.begin() as conn:
    conn.execute("""UPDATE surveys
                    SET question_ids_ordered = %s
                    WHERE survey_id = %s""",
                    question_ids_ordered, survey_id)
我收到的回溯是:

Traceback (most recent call last):
  File "foo.py", line 16, in <module>
    res = add_question_to_group(current_user, 46, 358, question_ids_ordered, new_group_name="Jellyfish?")
  File "/vagrant/workspace/panel/panel/survey.py", line 80, in add_question_to_group
    question_ids_ordered, survey_id)
  File "/home/vagrant/.virtualenvs/project/lib/python2.6/site-packages/sqlalchemy/engine/base.py", line 664, in execute
    params)
  File "/home/vagrant/.virtualenvs/project/lib/python2.6/site-packages/sqlalchemy/engine/base.py", line 808, in _execute_text
    statement, parameters
  File "/home/vagrant/.virtualenvs/project/lib/python2.6/site-packages/sqlalchemy/engine/base.py", line 831, in _execute_context
    None, None)
  File "/home/vagrant/.virtualenvs/project/lib/python2.6/site-packages/sqlalchemy/engine/base.py", line 827, in _execute_context
    context = constructor(dialect, self, conn, *args)
  File "/home/vagrant/.virtualenvs/project/lib/python2.6/site-packages/sqlalchemy/engine/default.py", line 513, in _init_statement
    for p in parameters]
sqlalchemy.exc.StatementError: 'int' object is not iterable (original cause: TypeError: 'int' object is not iterable) 'UPDATE surveys\n                        SET question_ids_ordered = %s\n                        WHERE survey_id = %s' ([237, 238, 239, 240, 241, 242, 243], 46)
回溯(最近一次呼叫最后一次):
文件“foo.py”,第16行,在
res=将问题添加到组(当前用户,46358,问题ID已订购,新组名称=“水母?”)
文件“/vagrant/workspace/panel/panel/survey.py”,第80行,在“将问题添加到”组中
问题(已订购id,调查id)
文件“/home/vagrant/.virtualenvs/project/lib/python2.6/site packages/sqlalchemy/engine/base.py”,第664行,在execute中
参数)
文件“/home/vagrant/.virtualenvs/project/lib/python2.6/site packages/sqlalchemy/engine/base.py”,第808行,文本
语句、参数
文件“/home/vagrant/.virtualenvs/project/lib/python2.6/site packages/sqlalchemy/engine/base.py”,第831行,在执行上下文中
没有,没有)
文件“/home/vagrant/.virtualenvs/project/lib/python2.6/site packages/sqlalchemy/engine/base.py”,第827行,在执行上下文中
上下文=构造函数(方言、self、conn、*args)
文件“/home/vagrant/.virtualenvs/project/lib/python2.6/site packages/sqlalchemy/engine/default.py”,第513行,在_init_语句中
对于参数中的p]
sqlalchemy.exc.StatementError:“int”对象不可iterable(原始原因:TypeError:“int”对象不可iterable)“更新调查\n设置问题\u id\u顺序=%s\n其中调查\u id=%s”([237,238,239,240,241,242,243],46)

我做错了什么?

如果您的表定义如下:

from datetime import datetime
from sqlalchemy import *
from sqlalchemy.dialects.postgresql import ARRAY

meta = MetaData()
surveys_table = Table('surveys', meta,
    Column('surveys_id', Integer, primary_key=True),
    Column('questions_ids_ordered', ARRAY(Integer)),
    Column('created_at', DateTime, nullable=False, default=datetime.utcnow)
)
然后,您可以通过以下方式简单地更新阵列(与psycopg2一起使用):

或者,如果愿意,可以使用
text()
construct()编写原始SQL:

from sqlalchemy.sql import text
with engine.connect() as conn:
    u = text('UPDATE surveys SET questions_ids_ordered = :q WHERE id = :id')
    conn.execute(u, q=[237, 238, 239, 240, 241, 242, 243], id=46)

如果您使用的是原始SQL,为什么不完全抛弃ORM呢?请阅读。在这个例子中,我没有使用ORM。我也没有在我的应用程序的任何地方使用ORM;我使用的是SQLAlchemy核心,而不是ORM。ORM是SQLAlchemy最好的部分,因为它提供了可移植性和可重用查询(使用字符串连接构建原始SQL很糟糕)。出于好奇,SQLAlchemy Core给了您什么Psycopg2没有的?我用多值子句做了很多插入。手工操作意味着大量冗余代码(或我不太喜欢的一次性函数)。SQLAlchemy使这些类型的插入变得容易,此外还使用了一个连接池,非常方便。谢谢您的回答。您能帮我在SQL中完成这项工作吗?好的,尽管我认为使用SA表达式看起来更好。不确定为什么将字符串和参数直接传递给
execute()
不起作用,但在使用
text()
构造时会起作用。我也同意SA表达式看起来更干净,但在使用这样的数组参数的情况下,我通过4或5个表连接。在我看来,当涉及这么多连接时,普通SQL更容易阅读和理解。现在,您将如何在该数组中附加一个值?@whowknows请将您的问题作为单独的问题发布,而不是在无关问题答案的注释中发布。
from sqlalchemy.sql import text
with engine.connect() as conn:
    u = text('UPDATE surveys SET questions_ids_ordered = :q WHERE id = :id')
    conn.execute(u, q=[237, 238, 239, 240, 241, 242, 243], id=46)