Hello!
If you execute a simple parameterized query using AsyncSession, like:
# db_session is instance of AsyncSession
stmt = text('SET local statement_timeout = :value').bindparams(value=500)
await db_session.execute(stmt)
you end up with:
E sqlalchemy.exc.ProgrammingError: (sqlalchemy.dialects.postgresql.asyncpg.ProgrammingError) <class 'asyncpg.exceptions.PostgresSyntaxError'>: syntax error at or near "$1"
E [SQL: SET local statement_timeout = %s]
E [parameters: (500,)]
E (Background on this error at: https://sqlalche.me/e/14/f405)
But it perfectly works if you just use an f-string, but using f-string does not sound cool.
I’ve found some explanations from asyncpg side (MagicStack/asyncpg#605 (comment)):
asyncpg does not do query argument interpolation in any form. The query you write gets passed directly to PostgreSQL. This is unlike psycopg2 which has extensive query rewriting/interpolation mechanisms.
Is it maybe fixable on SQLAlchemy side? Like SQLAlchemy passes asyncpg queries with parameter values already placed.
Hi,
The same error happens if you run the same query with asyncpg:
>>> async def go(): ... conn = await asyncpg.connect('postgresql://scott:tiger@localhost:5432/test') ... await conn.execute('SET local statement_timeout = $1', 1000) >>> asyncio.run(go()) Traceback (most recent call last): ... File "asyncpg\protocol\protocol.pyx", line 168, in prepare asyncpg.exceptions.PostgresSyntaxError: syntax error at or near "$1"
The issue here seems of asyncpg and in part of postgresql that does not accept parameters in that query. My suggestion is to ask for advice in the asyncpg repository.
Is it maybe fixable on SQLAlchemy side? Like SQLAlchemy passes asyncpg queries with parameter values already placed.
No, this is not something SQLAlchemy does, and in general not something we are interested in doing, since it has a lot of security implications
3 replies
Thanks for suggestions.
My suggestion is to ask for advice in the asyncpg repository.
Somebody already asked some time ago -> MagicStack/asyncpg#605
and unfortunately their answer is:
This is outside of scope and can be solved by a wrapper library.
Somebody already asked some time ago -> MagicStack/asyncpg#605
It was for a different case ,a create table compared to a set, but I guess the answer should be similar also for this query.
In my python code using asyncpg, I am passing in a tuple (‘PENDING’,) into a where-in query, which is logged as:
args=('TYPE_1', ('PENDING',))
query=SELECT * FROM actions where type = $1 AND status IN $2
It seems like the sql query should finally be
SELECT * FROM actions where type = TYPE_1 AND status in ('PENDING',);
but the above code results in:
asyncpg.exceptions.PostgresSyntaxError: syntax error at or near "$2"
I think it probably is because of the trailing comma in the tuple, but I don’t know how to get rid of it..
Hello!
If you execute a simple parameterized query using AsyncSession, like:
# db_session is instance of AsyncSession
stmt = text('SET local statement_timeout = :value').bindparams(value=500)
await db_session.execute(stmt)
you end up with:
E sqlalchemy.exc.ProgrammingError: (sqlalchemy.dialects.postgresql.asyncpg.ProgrammingError) <class 'asyncpg.exceptions.PostgresSyntaxError'>: syntax error at or near "$1"
E [SQL: SET local statement_timeout = %s]
E [parameters: (500,)]
E (Background on this error at: https://sqlalche.me/e/14/f405)
But it perfectly works if you just use an f-string, but using f-string does not sound cool.
I’ve found some explanations from asyncpg side (MagicStack/asyncpg#605 (comment)):
asyncpg does not do query argument interpolation in any form. The query you write gets passed directly to PostgreSQL. This is unlike psycopg2 which has extensive query rewriting/interpolation mechanisms.
Is it maybe fixable on SQLAlchemy side? Like SQLAlchemy passes asyncpg queries with parameter values already placed.
You must be logged in to vote
Hi,
The same error happens if you run the same query with asyncpg:
>>> async def go(): ... conn = await asyncpg.connect('postgresql://scott:tiger@localhost:5432/test') ... await conn.execute('SET local statement_timeout = $1', 1000) >>> asyncio.run(go()) Traceback (most recent call last): ... File "asyncpgprotocolprotocol.pyx", line 168, in prepare asyncpg.exceptions.PostgresSyntaxError: syntax error at or near "$1"
The issue here seems of asyncpg and in part of postgresql that does not accept parameters in that query. My suggestion is to ask for advice in the asyncpg repository.
Is it maybe fixable on SQLAlchemy side? Like SQLAlchemy passes asyncpg queries with parameter values already placed.
No, this is not something SQLAlchemy does, and in general not something we are interested in doing, since it has a lot of security implications
You must be logged in to vote
3 replies
Thanks for suggestions.
My suggestion is to ask for advice in the asyncpg repository.
Somebody already asked some time ago -> MagicStack/asyncpg#605
and unfortunately their answer is:
This is outside of scope and can be solved by a wrapper library.
Somebody already asked some time ago -> MagicStack/asyncpg#605
It was for a different case ,a create table compared to a set, but I guess the answer should be similar also for this query.
Я все еще изучаю PostgreSQL. Во время тестирования я использовал оператор INSERT только в psycopg2, а теперь и в asyncpg. Теперь мне нужно ОБНОВЛЯТЬ данные в моей тестовой базе данных вместо того, чтобы заменять их все.
В настоящее время я пытаюсь выполнить простой тест замены в таблице тестирования, прежде чем перейти к таблице разработки с дополнительными данными.
Я хочу заменить любое имя $ 1, находящееся в CONFLICT, на имя, которое уже есть в таблице users. Я пробую код запроса, который передается в БД через asyncpg. Я продолжаю получать синтаксические ошибки, поэтому я немного не понимаю, как исправить эти ошибки.
Каков правильный синтаксис этого запроса?
'''INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE "users"
SET name = 'TEST'
WHERE name = excluded.name '''
Обновлено:
Я получаю это сообщение об ошибке при использовании asyncpg:
asyncpg.exceptions.PostgresSyntaxError: syntax error at or near ""users""
Я получаю это сообщение об ошибке при использовании psycopg2:
psycopg2.ProgrammingError: syntax error at or near ""users""
Это код asyncpg, который я использовал для вставки INSERT:
async def insert_new_records(self, sql_command, data):
print (sql_command)
async with asyncpg.create_pool(**DB_CONN_INFO, command_timeout=60) as pool:
async with pool.acquire() as conn:
try:
stmt = await conn.prepare(sql_command)
async with conn.transaction():
for value in data:
async for item in stmt.cursor(*value):
pass
finally:
await pool.release(conn)
test_sql_command = '''
INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE "users"
SET name = 'TEST'
WHERE name = excluded.name '''
# The name 'HELLO WORLD' exists in the table, but the other name does not.
params = [('HELLO WORLD', datetime.date(1984, 3, 1)),
('WORLD HELLO', datetime.date(1984, 3, 1))]
loop = asyncio.get_event_loop()
loop.run_until_complete(db.insert_new_records(test_sql_command, params))
из таблицы?
info = await db.connection.fetch(«SELECT * FROM users») это не работает, бьет ошибку
asyncpg.exceptions.PostgresSyntaxError: ошибка синтаксиса (примерное положение: «)»)
python
russian
programming
20:35 18.06.2022
3
ответов
Во-первых, фетчолл. Во-вторых, это не похоже на тот код, в котором такая ошибка.
20:44 18.06.2022
𝓐𝓶𝓪𝓻𝓸 𝓥𝓲𝓽𝓪 ☕️
Во-первых, фетчолл. Во-вторых, это не похоже на то…
разобрался уже, спсаибо
20:44 18.06.2022
xtemple
разобрался уже, спсаибо
И вообще,
где экзекьют? =)
20:45 18.06.2022
Похожие вопросы
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
из таблицы?
info = await db.connection.fetch(«SELECT * FROM users») это не работает, бьет ошибку
asyncpg.exceptions.PostgresSyntaxError: ошибка синтаксиса (примерное положение: «)»)
python
russian
programming
3
ответов
Во-первых, фетчолл. Во-вторых, это не похоже на тот код, в котором такая ошибка.
xtemple
разобрался уже, спсаибо
И вообще,
где экзекьют? =)
Похожие вопросы
Обсуждают сегодня
Хм. Получается если я хочу использовать snackbar для отображения ошибки я не могу использовать streamBuilder для отлова ошибки и отображения через него? Я просто попробовал вы…
Anatoliy
14
Как относитесь к использованию flatMap()? Часто юзаете?
Антон
11
кто какими аналогами пользуется?
Alexandr ∨∧‾ Emelyanov
11
всем привет, есть ли у кого то темплейты для архитектуры телеграм ботов? Или книги, статьи
ъ
10
Коллеги, подскажите плиз, я правильно понял, что если sink-коннектор на кластер ставится, то параметр kafka_num_consumers определяет общее количество потребителей на весь клас…
Андрей Лысенко
7
Привет, почему подсвечивает что я написал не верный код? Я с недавних пор работаю в VS… C#
ㅤㅤㅤㅤㅤㅤ
6
кто что использует аналогичное постману? нужна альтернатива
Alexandr ∨∧‾ Emelyanov
6
Салют ребят, сталкивался кто с таким. есть таблица 1 с записями. Есть таблица 2 которая содержит поле string 1,33,40 (id строк из таблицы 1 через запятую) как можно прокинуть …
Кирилл Петрукович
6
Подскажите, что лучше: Podman или Docker?
Tommy
5
Привет ребят! Ищу хостинг провайдера для покупки VPS. Может кто подсказать какой хостинг лучше?
Vitaliy Yurakh
5
Hello!
If you execute a simple parameterized query using AsyncSession, like:
# db_session is instance of AsyncSession
stmt = text('SET local statement_timeout = :value').bindparams(value=500)
await db_session.execute(stmt)
you end up with:
E sqlalchemy.exc.ProgrammingError: (sqlalchemy.dialects.postgresql.asyncpg.ProgrammingError) <class 'asyncpg.exceptions.PostgresSyntaxError'>: syntax error at or near "$1"
E [SQL: SET local statement_timeout = %s]
E [parameters: (500,)]
E (Background on this error at: https://sqlalche.me/e/14/f405)
But it perfectly works if you just use an f-string, but using f-string does not sound cool.
I’ve found some explanations from asyncpg side (MagicStack/asyncpg#605 (comment)):
asyncpg does not do query argument interpolation in any form. The query you write gets passed directly to PostgreSQL. This is unlike psycopg2 which has extensive query rewriting/interpolation mechanisms.
Is it maybe fixable on SQLAlchemy side? Like SQLAlchemy passes asyncpg queries with parameter values already placed.
You must be logged in to vote
Hi,
The same error happens if you run the same query with asyncpg:
>>> async def go(): ... conn = await asyncpg.connect('postgresql://scott:tiger@localhost:5432/test') ... await conn.execute('SET local statement_timeout = $1', 1000) >>> asyncio.run(go()) Traceback (most recent call last): ... File "asyncpgprotocolprotocol.pyx", line 168, in prepare asyncpg.exceptions.PostgresSyntaxError: syntax error at or near "$1"
The issue here seems of asyncpg and in part of postgresql that does not accept parameters in that query. My suggestion is to ask for advice in the asyncpg repository.
Is it maybe fixable on SQLAlchemy side? Like SQLAlchemy passes asyncpg queries with parameter values already placed.
No, this is not something SQLAlchemy does, and in general not something we are interested in doing, since it has a lot of security implications
You must be logged in to vote
3 replies
Thanks for suggestions.
My suggestion is to ask for advice in the asyncpg repository.
Somebody already asked some time ago -> MagicStack/asyncpg#605
and unfortunately their answer is:
This is outside of scope and can be solved by a wrapper library.
Somebody already asked some time ago -> MagicStack/asyncpg#605
It was for a different case ,a create table compared to a set, but I guess the answer should be similar also for this query.
You need a primary key (or unique columns) to use ON CONFLICT
, so you have to define the table as
CREATE TABLE my_table
(
cat BIGINT PRIMARY KEY, --!!
roles BIGINT ARRAY
);
The column roles
is ambiguous in UPDATE
, fix it specifing the table name:
await connection.execute('' ' INSERT INTO my_table(cat, roles) VALUES($1, $2) ON CONFLICT(cat) DO UPDATE SET roles = array_cat(my_table.roles, $2) '' ', cat, roles)
Note that the function array_append()
appends an element to an array. You can use array_cat()
instead. However, it may lead to duplicated elements in a single array. If your aim is to have distinct elements in arrays, you should define a custom function in Postgres:
create or replace function public.array_merge(anyarray, anyarray) returns anyarray language sql as $function$ select array( select unnest($1) union select unnest($2) order by unnest ) $function$;
Suggestion : 2
The issue here seems of asyncpg and in part of postgresql that does not accept parameters in that query. My suggestion is to ask for advice in the asyncpg repository.,No, this is not something SQLAlchemy does, and in general not something we are interested in doing, since it has a lot of security implications,It was for a different case ,a create table compared to a set, but I guess the answer should be similar also for this query.,asyncpg does not do query argument interpolation in any form. The query you write gets passed directly to PostgreSQL. This is unlike psycopg2 which has extensive query rewriting/interpolation mechanisms.
# db_session is instance of AsyncSession stmt = text('SET local statement_timeout = :value').bindparams(value = 500) await db_session.execute(stmt)
E sqlalchemy.exc.ProgrammingError: (sqlalchemy.dialects.postgresql.asyncpg.ProgrammingError) <class 'asyncpg.exceptions.PostgresSyntaxError'>: syntax error at or near "$1" E [SQL: SET local statement_timeout = %s] E [parameters: (500,)] E (Background on this error at: https:
>>> async def go(): ...conn = await asyncpg.connect('postgresql://scott:tiger@localhost:5432/test') ...await conn.execute('SET local statement_timeout = $1', 1000) >>> asyncio.run(go()) Traceback(most recent call last): ... File "asyncpgprotocolprotocol.pyx", line 168, in prepare asyncpg.exceptions.PostgresSyntaxError: syntax error at or near "$1"
Suggestion : 3
Notice the use of the syntax $1.salary to select one field of the argument row value. Also notice how the calling SELECT command uses table_name.* to select the entire current row of a table as a composite value. The table row can alternatively be referenced using just the table name, like this:,In the last SELECT, notice that no output row appears for Child2, Child3, etc. This happens because listchildren returns an empty set for those arguments, so no result rows are generated. This is the same behavior as we got from an inner join to the function result when using the LATERAL syntax.,This prevents expansion of the function’s variadic parameter into its element type, thereby allowing the array argument value to match normally. VARIADIC can only be attached to the last actual argument of a function call.,In the older numeric approach, arguments are referenced using the syntax $n: $1 refers to the first input argument, $2 to the second, and so on. This will work whether or not the particular argument was declared with a name.
SQL function arguments can only be used as data values, not as identifiers. Thus for example this is reasonable:
INSERT INTO mytable VALUES($1);
but this will not work:
INSERT INTO $1 VALUES(42);
The simplest possible SQL function has no arguments and simply returns a base type, such as integer
:
CREATE FUNCTION one() RETURNS integer AS $$ SELECT 1 AS result; $$ LANGUAGE SQL; --Alternative syntax for string literal: CREATE FUNCTION one() RETURNS integer AS ' SELECT 1 AS result; ' LANGUAGE SQL; SELECT one(); one -- -- - 1
It is almost as easy to define SQL functions that take base types as arguments:
CREATE FUNCTION add_em(x integer, y integer) RETURNS integer AS $$ SELECT x + y; $$ LANGUAGE SQL; SELECT add_em(1, 2) AS answer; answer -- -- -- -- 3
Alternatively, we could dispense with names for the arguments and use numbers:
CREATE FUNCTION add_em(integer, integer) RETURNS integer AS $$ SELECT $1 + $2; $$ LANGUAGE SQL; SELECT add_em(1, 2) AS answer; answer -- -- -- -- 3
A user could execute this function to debit account 17 by $100.00 as follows:
In practice one would probably like a more useful result from the function than a constant 1, so a more likely definition is:
CREATE FUNCTION tf1(accountno integer, debit numeric) RETURNS numeric AS $$ UPDATE bank SET balance = balance - debit WHERE accountno = tf1.accountno; SELECT balance FROM bank WHERE accountno = tf1.accountno; $$ LANGUAGE SQL;
When writing functions with arguments of composite types, we must not only specify which argument we want but also the desired attribute (field) of that argument. For example, suppose that emp
is a table containing employee data, and therefore also the name of the composite type of each row of the table. Here is a function double_salary
that computes what someone’s salary would be if it were doubled:
CREATE TABLE emp( name text, salary numeric, age integer, cubicle point ); INSERT INTO emp VALUES('Bill', 4200, 45, '(2,1)'); CREATE FUNCTION double_salary(emp) RETURNS numeric AS $$ SELECT $1.salary * 2 AS salary; $$ LANGUAGE SQL; SELECT name, double_salary(emp.*) AS dream FROM emp WHERE emp.cubicle~ = point '(2,1)'; name | dream -- -- -- + -- -- -- - Bill | 8400
Notice the use of the syntax $1.salary
to select one field of the argument row value. Also notice how the calling SELECT
command uses table_name
.*
to select the entire current row of a table as a composite value. The table row can alternatively be referenced using just the table name, like this:
SELECT name, double_salary(emp) AS dream FROM emp WHERE emp.cubicle~ = point '(2,1)';
Sometimes it is handy to construct a composite argument value on-the-fly. This can be done with the ROW
construct. For example, we could adjust the data being passed to the function:
SELECT name, double_salary(ROW(name, salary * 1.1, age, cubicle)) AS dream FROM emp;
We must ensure each expression’s type can be cast to that of the corresponding column of the composite type. Otherwise we’ll get errors like this:
ERROR: return type mismatch in function declared to return emp DETAIL: Final statement returns text instead of point at column 4.
A different way to define the same function is:
CREATE FUNCTION new_emp() RETURNS emp AS $$ SELECT ROW('None', 1000.0, 25, '(2,2)')::emp; $$ LANGUAGE SQL;
We must ensure each expression’s type can be cast to that of the corresponding column of the composite type. Otherwise we’ll get errors like this:
ERROR: return type mismatch in function declared to return emp DETAIL: Final statement returns text instead of point at column 4.
An alternative way of describing a function’s results is to define it with output parameters, as in this example:
CREATE FUNCTION add_em(IN x int, IN y int, OUT sum int) AS 'SELECT x + y' LANGUAGE SQL; SELECT add_em(3, 7); add_em -- -- -- -- 10 (1 row)
This is not essentially different from the version of add_em
shown in Section 38.5.2. The real value of output parameters is that they provide a convenient way of defining functions that return several columns. For example,
CREATE FUNCTION sum_n_product(x int, y int, OUT sum int, OUT product int) AS 'SELECT x + y, x * y' LANGUAGE SQL; SELECT * FROM sum_n_product(11, 42); sum | product -- -- - + -- -- -- -- - 53 | 462(1 row)
What has essentially happened here is that we have created an anonymous composite type for the result of the function. The above example has the same end result as
CREATE TYPE sum_prod AS(sum int, product int); CREATE FUNCTION sum_n_product(int, int) RETURNS sum_prod AS 'SELECT $1 + $2, $1 * $2' LANGUAGE SQL;
Output parameters are also supported in procedures, but they work a bit differently from functions. In CALL
commands, output parameters must be included in the argument list. For example, the bank account debiting routine from earlier could be written like this:
CREATE PROCEDURE tp1(accountno integer, debit numeric, OUT new_balance numeric) AS $$ UPDATE bank SET balance = balance - debit WHERE accountno = tp1.accountno RETURNING balance; $$ LANGUAGE SQL;
To call this procedure, an argument matching the OUT
parameter must be included. It’s customary to write NULL
:
CALL tp1(17, 100.0, NULL);
Я все еще изучаю PostgreSQL. Во время тестирования я использовал оператор INSERT только в psycopg2, а теперь и в asyncpg. Теперь мне нужно ОБНОВЛЯТЬ данные в моей тестовой базе данных вместо того, чтобы заменять их все.
В настоящее время я пытаюсь выполнить простой тест замены в таблице тестирования, прежде чем перейти к таблице разработки с дополнительными данными.
Я хочу заменить любое имя $ 1, находящееся в CONFLICT, на имя, которое уже есть в таблице users. Я пробую код запроса, который передается в БД через asyncpg. Я продолжаю получать синтаксические ошибки, поэтому я немного не понимаю, как исправить эти ошибки.
Каков правильный синтаксис этого запроса?
'''INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE "users"
SET name = 'TEST'
WHERE name = excluded.name '''
Обновлено:
Я получаю это сообщение об ошибке при использовании asyncpg:
asyncpg.exceptions.PostgresSyntaxError: syntax error at or near ""users""
Я получаю это сообщение об ошибке при использовании psycopg2:
psycopg2.ProgrammingError: syntax error at or near ""users""
Это код asyncpg, который я использовал для вставки INSERT:
async def insert_new_records(self, sql_command, data):
print (sql_command)
async with asyncpg.create_pool(**DB_CONN_INFO, command_timeout=60) as pool:
async with pool.acquire() as conn:
try:
stmt = await conn.prepare(sql_command)
async with conn.transaction():
for value in data:
async for item in stmt.cursor(*value):
pass
finally:
await pool.release(conn)
test_sql_command = '''
INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE "users"
SET name = 'TEST'
WHERE name = excluded.name '''
# The name 'HELLO WORLD' exists in the table, but the other name does not.
params = [('HELLO WORLD', datetime.date(1984, 3, 1)),
('WORLD HELLO', datetime.date(1984, 3, 1))]
loop = asyncio.get_event_loop()
loop.run_until_complete(db.insert_new_records(test_sql_command, params))
Life, 9 ноября 2018 г., 17:36
1
1 567
2
You don’t pass the arguments in f-strings
when dealing with SQL queries, the syntax for query arguments in asyncpg
is $n
, also I see that you’re using the Connection.fetch
method but you’re simply updating the table, I’d suggest you to use Connection.execute
Your code fixed:
end_date = # Should be a datetime.datetime instance
await conn.execute("""
UPDATE blacklist
SET time = $1
WHERE username = $2
""", end_date, member.id)
Removing timezone awareness
end_date = # `datetime.datetime` instance
naive = end_date.replace(tzinfo=None)
await conn.execute("""
UPDATE blacklist
SET time = $1
WHERE username = $2
""", naive, member.id)
References:
Connection.execute
PS: Don’t create a new connection everytime you want to use it, normal practice is to have one long-term database connection
Вам нужны одинарные кавычки вокруг значения имени: SET name='TEST'
Двойные кавычки предназначены для имен таблиц или столбцов. В вашем случае вы можете просто удалить двойные кавычки вокруг users
,
После редактирования: вы действительно должны попробовать свои команды SQL в консоли базы данных, это не имеет ничего общего ни с python, ни с async. Это чистый синтаксис postgresql.
Итак, вторая проблема в вашем запросе заключается в том, что вы не должны указывать «пользователей» после ОБНОВЛЕНИЯ. Подразумевается, что вы обновляете ту же таблицу. Так просто DO UPDATE SET...
это хорошо.
Тогда вы получите column reference "name" is ambiguous
, Ты должен написать DO UPDATE SET name='TEST'
, Вы уже обновляете строку where name=excluded.name
, Я не на 100% понимаю, что вы пытаетесь сделать. Поэтому, если вы вставляете строку один раз, она вставляется как обычно. Если вы вставите его второй раз, имя будет заменено на «ТЕСТ». Исключенное ключевое слово позволяет получить доступ к попыткам вставки значений. Так, например, если вы хотите обновить last_access
столбец при попытке вставить существующее имя, вы должны написать ON CONFLICT (name) DO UPDATE last_access=excluded.last_access
,
В моем коде Python, использующем asyncpg, я передаю кортеж (‘PENDING’,) в запрос where-in, который регистрируется как:
args=('TYPE_1', ('PENDING',))
query=SELECT * FROM actions where type = $1 AND status IN $2
Похоже, что SQL-запрос, наконец, должен быть
SELECT * FROM actions where type = TYPE_1 AND status in ('PENDING',);
Но приведенный выше код приводит к:
asyncpg.exceptions.PostgresSyntaxError: syntax error at or near "$2"
Я думаю, что это, вероятно, из-за запятой в кортеже, но я не знаю, как от нее избавиться ..
1 ответ
В случае, если это может помочь другим людям. В asyncpg WHERE IN больше не поддерживается. Правильный способ — использовать ANY
, поэтому при генерации SQL-кодов это должно быть:
WHERE type = $1 AND status = ANY($2::text[])
Где $ 2 — обычный список питонов. Глядя на args
, теперь это:
('TYPE_1', ['PENDING'])
7
jamesdeath123
13 Сен 2019 в 23:53
I’m still learning PostgreSQL. During my testing, I have only been using INSERT statement in either psycopg2 and now asyncpg. I now have the need to UPDATE data in my test database, instead of replacing all of it.
I’m currently trying to do a simple replacement test in a testing table, before I move to development table with more data.
I want to replace any $1 name that is in CONFLICT with a name that is already in the table users. I’m trying the query code, which is passed to the DB via asyncpg. I keep getting a syntax errors, so I’m a little lost on how to correct these errors.
What is the proper syntax for this query?
'''INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE "users"
SET name = 'TEST'
WHERE name = excluded.name '''
UPDATE:
I’m getting this error message when using asyncpg:
asyncpg.exceptions.PostgresSyntaxError: syntax error at or near ""users""
I’m getting this error message when using psycopg2:
psycopg2.ProgrammingError: syntax error at or near ""users""
This is the asyncpg code that I have been using to do the INSERTs:
async def insert_new_records(self, sql_command, data):
print (sql_command)
async with asyncpg.create_pool(**DB_CONN_INFO, command_timeout=60) as pool:
async with pool.acquire() as conn:
try:
stmt = await conn.prepare(sql_command)
async with conn.transaction():
for value in data:
async for item in stmt.cursor(*value):
pass
finally:
await pool.release(conn)
test_sql_command = '''
INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE "users"
SET name = 'TEST'
WHERE name = excluded.name '''
# The name 'HELLO WORLD' exists in the table, but the other name does not.
params = [('HELLO WORLD', datetime.date(1984, 3, 1)),
('WORLD HELLO', datetime.date(1984, 3, 1))]
loop = asyncio.get_event_loop()
loop.run_until_complete(db.insert_new_records(test_sql_command, params))
python-3.x postgresql psycopg2 asyncpg
edited Nov 9 ’18 at 18:40
Life is complexLife is complex
I’m still learning PostgreSQL. During my testing, I have only been using INSERT statement in either psycopg2 and now asyncpg. I now have the need to UPDATE data in my test database, instead of replacing all of it.
I’m currently trying to do a simple replacement test in a testing table, before I move to development table with more data.
I want to replace any $1 name that is in CONFLICT with a name that is already in the table users. I’m trying the query code, which is passed to the DB via asyncpg. I keep getting a syntax errors, so I’m a little lost on how to correct these errors.
What is the proper syntax for this query?
'''INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE "users"
SET name = 'TEST'
WHERE name = excluded.name '''
UPDATE:
I’m getting this error message when using asyncpg:
asyncpg.exceptions.PostgresSyntaxError: syntax error at or near ""users""
I’m getting this error message when using psycopg2:
psycopg2.ProgrammingError: syntax error at or near ""users""
This is the asyncpg code that I have been using to do the INSERTs:
async def insert_new_records(self, sql_command, data):
print (sql_command)
async with asyncpg.create_pool(**DB_CONN_INFO, command_timeout=60) as pool:
async with pool.acquire() as conn:
try:
stmt = await conn.prepare(sql_command)
async with conn.transaction():
for value in data:
async for item in stmt.cursor(*value):
pass
finally:
await pool.release(conn)
test_sql_command = '''
INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE "users"
SET name = 'TEST'
WHERE name = excluded.name '''
# The name 'HELLO WORLD' exists in the table, but the other name does not.
params = [('HELLO WORLD', datetime.date(1984, 3, 1)),
('WORLD HELLO', datetime.date(1984, 3, 1))]
loop = asyncio.get_event_loop()
loop.run_until_complete(db.insert_new_records(test_sql_command, params))
python-3.x postgresql psycopg2 asyncpg
edited Nov 9 ’18 at 18:40
Life is complexLife is complex
1
1
I’m still learning PostgreSQL. During my testing, I have only been using INSERT statement in either psycopg2 and now asyncpg. I now have the need to UPDATE data in my test database, instead of replacing all of it.
I’m currently trying to do a simple replacement test in a testing table, before I move to development table with more data.
I want to replace any $1 name that is in CONFLICT with a name that is already in the table users. I’m trying the query code, which is passed to the DB via asyncpg. I keep getting a syntax errors, so I’m a little lost on how to correct these errors.
What is the proper syntax for this query?
'''INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE "users"
SET name = 'TEST'
WHERE name = excluded.name '''
UPDATE:
I’m getting this error message when using asyncpg:
asyncpg.exceptions.PostgresSyntaxError: syntax error at or near ""users""
I’m getting this error message when using psycopg2:
psycopg2.ProgrammingError: syntax error at or near ""users""
This is the asyncpg code that I have been using to do the INSERTs:
async def insert_new_records(self, sql_command, data):
print (sql_command)
async with asyncpg.create_pool(**DB_CONN_INFO, command_timeout=60) as pool:
async with pool.acquire() as conn:
try:
stmt = await conn.prepare(sql_command)
async with conn.transaction():
for value in data:
async for item in stmt.cursor(*value):
pass
finally:
await pool.release(conn)
test_sql_command = '''
INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE "users"
SET name = 'TEST'
WHERE name = excluded.name '''
# The name 'HELLO WORLD' exists in the table, but the other name does not.
params = [('HELLO WORLD', datetime.date(1984, 3, 1)),
('WORLD HELLO', datetime.date(1984, 3, 1))]
loop = asyncio.get_event_loop()
loop.run_until_complete(db.insert_new_records(test_sql_command, params))
python-3.x postgresql psycopg2 asyncpg
edited Nov 9 ’18 at 18:40
Life is complexLife is complex
I’m still learning PostgreSQL. During my testing, I have only been using INSERT statement in either psycopg2 and now asyncpg. I now have the need to UPDATE data in my test database, instead of replacing all of it.
I’m currently trying to do a simple replacement test in a testing table, before I move to development table with more data.
I want to replace any $1 name that is in CONFLICT with a name that is already in the table users. I’m trying the query code, which is passed to the DB via asyncpg. I keep getting a syntax errors, so I’m a little lost on how to correct these errors.
What is the proper syntax for this query?
'''INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE "users"
SET name = 'TEST'
WHERE name = excluded.name '''
UPDATE:
I’m getting this error message when using asyncpg:
asyncpg.exceptions.PostgresSyntaxError: syntax error at or near ""users""
I’m getting this error message when using psycopg2:
psycopg2.ProgrammingError: syntax error at or near ""users""
This is the asyncpg code that I have been using to do the INSERTs:
async def insert_new_records(self, sql_command, data):
print (sql_command)
async with asyncpg.create_pool(**DB_CONN_INFO, command_timeout=60) as pool:
async with pool.acquire() as conn:
try:
stmt = await conn.prepare(sql_command)
async with conn.transaction():
for value in data:
async for item in stmt.cursor(*value):
pass
finally:
await pool.release(conn)
test_sql_command = '''
INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE "users"
SET name = 'TEST'
WHERE name = excluded.name '''
# The name 'HELLO WORLD' exists in the table, but the other name does not.
params = [('HELLO WORLD', datetime.date(1984, 3, 1)),
('WORLD HELLO', datetime.date(1984, 3, 1))]
loop = asyncio.get_event_loop()
loop.run_until_complete(db.insert_new_records(test_sql_command, params))
python-3.x postgresql psycopg2 asyncpg
python-3.x postgresql psycopg2 asyncpg
edited Nov 9 ’18 at 18:40
Life is complexLife is complex
edited Nov 9 ’18 at 18:40
Life is complexLife is complex
edited Nov 9 ’18 at 18:40
edited Nov 9 ’18 at 18:40
edited Nov 9 ’18 at 18:40
Life is complexLife is complex
Life is complexLife is complex
Life is complexLife is complex
You need single quotes around the value for name: SET name='TEST'
The double quotes are for table or column names. In your case, you could just remove the double quotes around users
.
After edit:
You should really try your SQL commands in the database console, this has nothing to do with python nor async. It’s pure postgresql syntax.
So, the second issue in your query is that you shouldn’t specify «users» after UPDATE. It’s implied that you’re updating the same table. So just DO UPDATE SET...
is good.
Then, you’ll get column reference "name" is ambiguous
. You should write DO UPDATE SET name='TEST'
. You already are updating the row where name=excluded.name
. I am not 100% clear on what you’re trying to do. So if you insert a row once, it’s inserted as usual. If you insert it a second time, the name is replaced with ‘TEST’. The excluded keyword allows you to access the attempted insert values. So for example, if you wanted to update the last_access
column when trying to insert an existing name, you would write ON CONFLICT (name) DO UPDATE last_access=excluded.last_access
.
edited Nov 10 ’18 at 12:31
answered Nov 9 ’18 at 17:05
you can test
replace :
»’INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE «users»
SET name = ‘TEST’
WHERE name = excluded.name »’
by :
«»»INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE
SET name = ‘TEST’
WHERE name = excluded.name «»»
answered Nov 23 ’18 at 22:51
Your Answer
StackExchange.ifUsing(«editor», function () {
StackExchange.using(«externalEditor», function () {
StackExchange.using(«snippets», function () {
StackExchange.snippets.init();
});
});
}, «code-snippets»);
StackExchange.ready(function() {
var channelOptions = {
tags: «».split(» «),
id: «1»
};
initTagRenderer(«».split(» «), «».split(» «), channelOptions);
StackExchange.using(«externalEditor», function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using(«snippets», function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: ‘answer’,
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: «»,
imageUploader: {
brandingHtml: «Powered by u003ca class=»icon-imgur-white» href=»https://imgur.com/»u003eu003c/au003e»,
contentPolicyHtml: «User contributions licensed under u003ca href=»https://creativecommons.org/licenses/by-sa/3.0/»u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href=»https://stackoverflow.com/legal/content-policy»u003e(content policy)u003c/au003e»,
allowUrls: true
},
onDemand: true,
discardSelector: «.discard-answer»
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave(‘#login-link’);
});
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin(‘.new-post-login’, ‘https%3a%2f%2fstackoverflow.com%2fquestions%2f53229783%2fupsert-syntax-error-linked-to-update-in-postgresql-python%23new-answer’, ‘question_page’);
}
);
Post as a guest
Required, but never shown
You need single quotes around the value for name: SET name='TEST'
The double quotes are for table or column names. In your case, you could just remove the double quotes around users
.
After edit:
You should really try your SQL commands in the database console, this has nothing to do with python nor async. It’s pure postgresql syntax.
So, the second issue in your query is that you shouldn’t specify «users» after UPDATE. It’s implied that you’re updating the same table. So just DO UPDATE SET...
is good.
Then, you’ll get column reference "name" is ambiguous
. You should write DO UPDATE SET name='TEST'
. You already are updating the row where name=excluded.name
. I am not 100% clear on what you’re trying to do. So if you insert a row once, it’s inserted as usual. If you insert it a second time, the name is replaced with ‘TEST’. The excluded keyword allows you to access the attempted insert values. So for example, if you wanted to update the last_access
column when trying to insert an existing name, you would write ON CONFLICT (name) DO UPDATE last_access=excluded.last_access
.
edited Nov 10 ’18 at 12:31
answered Nov 9 ’18 at 17:05
You need single quotes around the value for name: SET name='TEST'
The double quotes are for table or column names. In your case, you could just remove the double quotes around users
.
After edit:
You should really try your SQL commands in the database console, this has nothing to do with python nor async. It’s pure postgresql syntax.
So, the second issue in your query is that you shouldn’t specify «users» after UPDATE. It’s implied that you’re updating the same table. So just DO UPDATE SET...
is good.
Then, you’ll get column reference "name" is ambiguous
. You should write DO UPDATE SET name='TEST'
. You already are updating the row where name=excluded.name
. I am not 100% clear on what you’re trying to do. So if you insert a row once, it’s inserted as usual. If you insert it a second time, the name is replaced with ‘TEST’. The excluded keyword allows you to access the attempted insert values. So for example, if you wanted to update the last_access
column when trying to insert an existing name, you would write ON CONFLICT (name) DO UPDATE last_access=excluded.last_access
.
edited Nov 10 ’18 at 12:31
answered Nov 9 ’18 at 17:05
2
You need single quotes around the value for name: SET name='TEST'
The double quotes are for table or column names. In your case, you could just remove the double quotes around users
.
After edit:
You should really try your SQL commands in the database console, this has nothing to do with python nor async. It’s pure postgresql syntax.
So, the second issue in your query is that you shouldn’t specify «users» after UPDATE. It’s implied that you’re updating the same table. So just DO UPDATE SET...
is good.
Then, you’ll get column reference "name" is ambiguous
. You should write DO UPDATE SET name='TEST'
. You already are updating the row where name=excluded.name
. I am not 100% clear on what you’re trying to do. So if you insert a row once, it’s inserted as usual. If you insert it a second time, the name is replaced with ‘TEST’. The excluded keyword allows you to access the attempted insert values. So for example, if you wanted to update the last_access
column when trying to insert an existing name, you would write ON CONFLICT (name) DO UPDATE last_access=excluded.last_access
.
edited Nov 10 ’18 at 12:31
answered Nov 9 ’18 at 17:05
You need single quotes around the value for name: SET name='TEST'
The double quotes are for table or column names. In your case, you could just remove the double quotes around users
.
After edit:
You should really try your SQL commands in the database console, this has nothing to do with python nor async. It’s pure postgresql syntax.
So, the second issue in your query is that you shouldn’t specify «users» after UPDATE. It’s implied that you’re updating the same table. So just DO UPDATE SET...
is good.
Then, you’ll get column reference "name" is ambiguous
. You should write DO UPDATE SET name='TEST'
. You already are updating the row where name=excluded.name
. I am not 100% clear on what you’re trying to do. So if you insert a row once, it’s inserted as usual. If you insert it a second time, the name is replaced with ‘TEST’. The excluded keyword allows you to access the attempted insert values. So for example, if you wanted to update the last_access
column when trying to insert an existing name, you would write ON CONFLICT (name) DO UPDATE last_access=excluded.last_access
.
edited Nov 10 ’18 at 12:31
answered Nov 9 ’18 at 17:05
edited Nov 10 ’18 at 12:31
edited Nov 10 ’18 at 12:31
edited Nov 10 ’18 at 12:31
answered Nov 9 ’18 at 17:05
answered Nov 9 ’18 at 17:05
answered Nov 9 ’18 at 17:05
you can test
replace :
»’INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE «users»
SET name = ‘TEST’
WHERE name = excluded.name »’
by :
«»»INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE
SET name = ‘TEST’
WHERE name = excluded.name «»»
answered Nov 23 ’18 at 22:51
you can test
replace :
»’INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE «users»
SET name = ‘TEST’
WHERE name = excluded.name »’
by :
«»»INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE
SET name = ‘TEST’
WHERE name = excluded.name «»»
answered Nov 23 ’18 at 22:51
0
you can test
replace :
»’INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE «users»
SET name = ‘TEST’
WHERE name = excluded.name »’
by :
«»»INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE
SET name = ‘TEST’
WHERE name = excluded.name «»»
answered Nov 23 ’18 at 22:51
you can test
replace :
»’INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE «users»
SET name = ‘TEST’
WHERE name = excluded.name »’
by :
«»»INSERT INTO users(name, dob)
VALUES($1, $2)
ON CONFLICT (name)
DO
UPDATE
SET name = ‘TEST’
WHERE name = excluded.name «»»
answered Nov 23 ’18 at 22:51
answered Nov 23 ’18 at 22:51
answered Nov 23 ’18 at 22:51
answered Nov 23 ’18 at 22:51
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave(‘#login-link’);
});
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin(‘.new-post-login’, ‘https%3a%2f%2fstackoverflow.com%2fquestions%2f53229783%2fupsert-syntax-error-linked-to-update-in-postgresql-python%23new-answer’, ‘question_page’);
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave(‘#login-link’);
});
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave(‘#login-link’);
});
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave(‘#login-link’);
});
Sign up using Email and Password
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
из таблицы?
info = await db.connection.fetch(«SELECT * FROM users») это не работает, бьет ошибку
asyncpg.exceptions.PostgresSyntaxError: ошибка синтаксиса (примерное положение: «)»)
python
russian
programming
20:35 18.06.2022
3
ответов
Во-первых, фетчолл. Во-вторых, это не похоже на тот код, в котором такая ошибка.
20:44 18.06.2022
𝓐𝓶𝓪𝓻𝓸 𝓥𝓲𝓽𝓪 ☕️
Во-первых, фетчолл. Во-вторых, это не похоже на то…
разобрался уже, спсаибо
20:44 18.06.2022
xtemple
разобрался уже, спсаибо
И вообще,
где экзекьют? =)
20:45 18.06.2022
Похожие вопросы
Вам нужны одинарные кавычки вокруг значения имени: SET name='TEST'
Двойные кавычки предназначены для имен таблиц или столбцов. В вашем случае вы можете просто удалить двойные кавычки вокруг users
,
После редактирования: вы действительно должны попробовать свои команды SQL в консоли базы данных, это не имеет ничего общего ни с python, ни с async. Это чистый синтаксис postgresql.
Итак, вторая проблема в вашем запросе заключается в том, что вы не должны указывать «пользователей» после ОБНОВЛЕНИЯ. Подразумевается, что вы обновляете ту же таблицу. Так просто DO UPDATE SET...
это хорошо.
Тогда вы получите column reference "name" is ambiguous
, Ты должен написать DO UPDATE SET name='TEST'
, Вы уже обновляете строку where name=excluded.name
, Я не на 100% понимаю, что вы пытаетесь сделать. Поэтому, если вы вставляете строку один раз, она вставляется как обычно. Если вы вставите его второй раз, имя будет заменено на «ТЕСТ». Исключенное ключевое слово позволяет получить доступ к попыткам вставки значений. Так, например, если вы хотите обновить last_access
столбец при попытке вставить существующее имя, вы должны написать ON CONFLICT (name) DO UPDATE last_access=excluded.last_access
,