gpt4 book ai didi

python - django + 南 + python : strange behavior when using a text string received as a parameter in a function

转载 作者:太空宇宙 更新时间:2023-11-03 23:49:44 25 4
gpt4 key购买 nike

这是我的第一个问题。

我正在尝试在 django 中执行 SQL 查询(南迁):

from django.db import connection
# ...
class Migration(SchemaMigration):
# ...
def transform_id_to_pk(self, table):
try:
db.delete_primary_key(table)
except:
pass
finally:
cursor = connection.cursor()

# This does not work
cursor.execute('SELECT MAX("id") FROM "%s"', [table])

# I don't know if this works.
try:
minvalue = cursor.fetchone()[0]
except:
minvalue = 1
seq_name = table + '_id_seq'

db.execute('CREATE SEQUENCE "%s" START WITH %s OWNED BY "%s"."id"', [seq_name, minvalue, table])
db.execute('ALTER TABLE "%s" ALTER COLUMN id SET DEFAULT nextval("%s")', [table, seq_name + '::regclass'])
db.create_primary_key(table, ['id'])
# ...

我是这样使用这个函数的:

self.transform_id_to_pk('my_table_name')

所以它应该:

  1. 找到最大的现有 ID 或 0(崩溃)
  2. 创建序列名
  3. 创建序列
  4. 更新 ID 字段以使用序列
  5. 将 ID 更新为 PK

但它崩溃了,错误提示:

  File "../apps/accounting/migrations/0003_setup_tables.py", line 45, in forwards
self.delegation_table_setup(orm)
File "../apps/accounting/migrations/0003_setup_tables.py", line 478, in delegation_table_setup
self.transform_id_to_pk('accounting_delegation')
File "../apps/accounting/migrations/0003_setup_tables.py", line 20, in transform_id_to_pk
cursor.execute(u'SELECT MAX("id") FROM "%s"', [table.encode('utf-8')])
File "/Library/Python/2.6/site-packages/django/db/backends/util.py", line 19, in execute
return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: relation "E'accounting_delegation'" does not exist
LINE 1: SELECT MAX("id") FROM "E'accounting_delegation'"
^

为方便起见,我缩短了文件路径。

“E'accounting_delegation'”是什么意思?我怎样才能摆脱它?

谢谢!

卡洛斯。

最佳答案

问题是您正在对非 SQL 数据的事物使用 DB-API 参数化。当您执行以下操作时:

cursor.execute('INSERT INTO table_foo VALUES (%s, %s)', (col1, col2))

DB-API 模块(在这种情况下,无论你使用什么数据库,django 的前端)都会知道适本地转义 'col1' 和 'col2' 的内容,并用它们替换 %s。请注意,%s 周围没有引号。但这仅适用于 SQL 数据,不适用于 SQL 元数据,例如表名和序列名,因为它们需要以不同方式引用(或根本不需要引用)。你做

cursor.execute('INSERT INTO "%s" VALUES (%s, %s)', (tablename, col1, col2))

表名被引用,就好像你的意思是要插入的字符串数据一样,你最终得到的是,例如,“'table_foo'”。您需要将作为查询一部分的 SQL 元数据与不属于查询的 SQL 数据分开,如下所示:

sql = 'INSERT INTO TABLE "%s" VALUES (%%s, %%s)' % (tablename,)
cursor.execute(sql, (col1, col2))

请注意,因为 django DB-API 前端的参数样式是“pyformat”(它使用 %s 作为占位符),所以当您进行字符串格式化以创建要执行的 SQL 时,您需要转义它们。请注意,当您从不安全的来源获取表名并且不对其进行验证时,这对于 SQL 注入(inject)攻击是不安全的。

关于python - django + 南 + python : strange behavior when using a text string received as a parameter in a function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2636839/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com