从Django调用PostgreSQL存储过程报错:无匹配的存储过程
解决Django调用PostgreSQL存储过程的问题
一、先搞定迁移文件不生效的问题
Django的迁移文件不是随便建个.py就能被识别的,得按规则来:
- 文件名必须是
00xx_xxxx.py带序号的格式,比如0001_create_get_input_file_procedure.py,你手动建的test.pyDjango根本不认——它会靠序号、django_migrations表的记录来判断哪些迁移要执行。 - 迁移文件里必须包含符合规范的
Migration类,示例如下:
from django.db import migrations class Migration(migrations.Migration): # 依赖的前置迁移,比如你的app初始迁移是0000_initial,就填('api', '0000_initial'),没有就留空 dependencies = [('api', '0000_initial')] operations = [ migrations.RunSQL( """ CREATE OR REPLACE PROCEDURE get_input_file() LANGUAGE plpgsql AS $$ BEGIN -- 这里写你的存储过程逻辑 RAISE NOTICE '存储过程执行成功'; END; $$; """ ) ]
- 写完后直接执行
python manage.py migrate api,如果还是提示无迁移可应用,去数据库的django_migrations表看看有没有这条迁移的记录,有的话可以删掉再重新执行迁移。
二、解决存储过程不存在的报错
这个报错大概率是数据库里根本没创建出存储过程,先做确认:
- 直接登录PostgreSQL数据库,执行
\dRp查看所有存储过程,或者\dRp+ get_input_file精准查找。如果查不到,说明迁移没执行成功,先把上面的迁移问题解决。 - 如果数据库里确实有这个存储过程,调用时注意这几点:
- PostgreSQL的存储过程要用
CALL语句调用,psycopg2里的写法:
def your_view(request): # 用Django的数据库连接更方便,不用手动写连接信息 from django.db import connection with connection.cursor() as cur: try: # 两种调用方式选一个就行 cur.execute("CALL get_input_file();") # 或者 cur.callproc('get_input_file') connection.commit() except Exception as e: connection.rollback() print(f"调用失败:{e}") # 后续视图逻辑- 要是存储过程带参数,必须保证传递的参数类型和定义完全匹配,比如定义的是
get_input_file(file_id int),就不能传字符串类型的ID。 - 检查存储过程所在的schema,如果不在默认的
public下,调用时要指定全路径,比如CALL api.get_input_file();。
- PostgreSQL的存储过程要用
三、额外排查点
- 确认Django用的数据库账号和你手动登录的是同一个,并且该账号有创建、调用存储过程的权限。
- 可以直接在数据库客户端执行存储过程的创建SQL,看有没有语法错误——有时候迁移执行失败是因为SQL本身有问题,但Django没把错误信息抛出来。
内容的提问来源于stack exchange,提问作者SDido
相关产品推荐
相关产品推荐

