Я пытаюсь создать версию миграции alembic для создания пользовательской функции на сервере PostgreSQL версии 10.2, однако скрипт продолжает выдавать ошибку:
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) unterminated dollar-quoted string at or near "$body$
select string_agg(convert_to(coalesce(r[2], length(length(r[1])::text) || length(r[1])::text || r[1]), 'SQL_ASCII'), '"
LINE 6: as $body$
^
[SQL: "\n create or replace function naturalsort(text)\n returns bytea\n language sql\n immutable strict\n as $body$ \n select string_agg(convert_to(coalesce(r[2], length(length(r[1])::text) || length(r[1])::text || r[1]), 'SQL_ASCII'), '\x00') from regexp_matches($1, '0*([0-9]+)|([^0-9]+)', 'g') r; \n $body$;\n "] (Background on this error at: http://sqlalche.me/e/f405)
Скрипт, который я запускаю:
def upgrade():
conn = op.get_bind()
conn.execute('DROP FUNCTION IF EXISTS "naturalsort"')
conn.execute("""
create or replace function naturalsort(text)
returns bytea
language sql
immutable strict
as $body$
select string_agg(convert_to(coalesce(r[2], length(length(r[1])::text) || length(r[1])::text || r[1]), 'SQL_ASCII'), '\x00') from regexp_matches($1, '0*([0-9]+)|([^0-9]+)', 'g') r;
$body$;
""")
Код должен предусматривать естественную сортировку столбцов и является копией / вставкой из родиевой жабы .
Поскольку строки в кавычках в долларах - это способ переписать строковые константы, альтернативой может быть (обратите внимание на двойные одинарные кавычки в соответствии с документацией postgresql: «Чтобы включить символ одинарных кавычек в строковую константу, напишите два соседние одинарные кавычки, например, лошадь Дайанны. Обратите внимание, что это не то же самое, что символ двойной кавычки (")."):
conn.execute("""
create or replace function naturalsort(text)
returns bytea
language sql
immutable strict
as 'select string_agg(convert_to(coalesce(r[2], length(length(r[1])::text) || length(r[1])::text || r[1]), ''SQL_ASCII''), ''\x00'') from regexp_matches($1, ''0*([0-9]+)|([^0-9]+)'', ''g'') r;';
""")
однако это выдает похожую ошибку:
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) unterminated quoted string at or near "'select string_agg(convert_to(coalesce(r[2], length(length(r[1])::text) || length(r[1])::text || r[1]), ''SQL_ASCII''), ''"
LINE 6: as 'select string_agg(convert_to(coalesce(r[2], leng...
^
[SQL: "\n create or replace function naturalsort(text)\n returns bytea\n language sql\n immutable strict\n as 'select string_agg(convert_to(coalesce(r[2], length(length(r[1])::text) || length(r[1])::text || r[1]), ''SQL_ASCII''), ''\x00'') from regexp_matches($1, ''0*([0-9]+)|([^0-9]+)'', ''g'') r;';\n "] (Background on this error at: http://sqlalche.me/e/f405)
Странно то, что эти запросы прекрасно выполняются в pgAdmin, и alembic, похоже, генерирует допустимый SQL (alembic upgrade: --sql):
DROP FUNCTION IF EXISTS "naturalsort";
create or replace function naturalsort(text)
returns bytea
language sql
immutable strict
as $body$
select string_agg(convert_to(coalesce(r[2], length(length(r[1])::text) || length(r[1])::text || r[1]), 'SQL_ASCII'), '') from regexp_matches($1, '0*([0-9]+)|([^0-9]+)', 'g') r;
$body$;;
UPDATE alembic_version SET version_num='ad99fdcb28bc' WHERE alembic_version.version_num = 'ff00ac684617';
COMMIT;
Есть какие-нибудь подсказки, почему psycopg2 продолжает выдавать ошибку unterminated dollar-quoted string at or near "$body$
?