ОБНОВЛЕНИЕ См. Рецепт внизу для обхода проблемы
Я разработал некоторый пример кода, чтобы увидеть, что здесь делает psycopg2, и это хорошо в их сфере - psycopg2 не такинтерпретировать значение как массив вообще.psycopg2 должен иметь возможность анализировать ARRAY, когда он возвращается, поскольку тип ARRAY в SQLA предполагает, что, по крайней мере, многое было сделано.Вы, конечно, можете взломать ARRAY в SQLAlchemy, что в данном случае означало бы, что он вообще не используется в пользу чего-то, что анализирует это конкретное строковое значение, которое psycopg2 возвращает нам.и даже не используют механизм psycopg2 для преобразования таймдельт, что обычно не нужно беспокоить SQLAlchemy.В этом случае я чувствую, что возможности DBAPI используются недостаточно, а psycopg2 - очень способный DBAPI.
Поэтому я бы посоветовал вам поработать с механикой нестандартного типа psycopg2 на http://initd.org/psycopg/docs/extensions.html#database-types-casting-functions.
Если вы хотите отправить по почте список рассылки , вот тестовый пример:
import psycopg2
conn = psycopg2.connect(host="localhost", database="test", user="scott", password="tiger")
cursor = conn.cursor()
cursor.execute("""
create type my_pg_type as (
string_id varchar(32),
time_diff interval,
multiplier integer
)
""")
cursor.execute("""
CREATE TABLE my_table (
data my_pg_type[]
)
""")
cursor.execute("insert into my_table (data) "
"values (CAST(%(data)s AS my_pg_type[]))",
{'data':[("xyz", "'1 day 01:00:00'", 5), ("pqr", "'1 day 01:00:00'", 5)]})
cursor.execute("SELECT * from my_table")
row = cursor.fetchone()
assert isinstance(row[0], (tuple, list)), repr(row[0])
Регистрация типа PG поддерживает глобальную регистрацию.Вы также можете зарегистрировать типы для каждого соединения в SQLAlchemy, используя приемник пула в 0,6 или событие подключения в 0,7 и далее.
ОБНОВЛЕНИЕ - из-за https://bitbucket.org/zzzeek/sqlalchemy/issue/3467/array-of-enums-does-not-allow-assigning Я, вероятно, пока рекомендую людям использовать этот тип обходного пути, пока psycopg2 не добавит дополнительную встроенную поддержку для этого:
class ArrayOfEnum(ARRAY):
def bind_expression(self, bindvalue):
return sa.cast(bindvalue, self)
def result_processor(self, dialect, coltype):
super_rp = super(ArrayOfEnum, self).result_processor(dialect, coltype)
def handle_raw_string(value):
inner = re.match(r"^{(.*)}$", value).group(1)
return inner.split(",")
def process(value):
return super_rp(handle_raw_string(value))
return process