2013-04-22 3 views
3

SqlAlchemy поддерживает большинство типов данных, специфичных для базы данных, через диалекты, но я не смог найти ничего, что могло бы работать с типом столбца postgresql xml. Кто-нибудь знает рабочее решение. В идеале для него не требуется отдельная реализация типа столбцов.Использование типа данных postgresql xml с sqlalchemy

+0

Я не вижу, что реализуется в PostGreSQL диалектов с SQLAlchemy 0.8. Вы можете попробовать использовать рефлексию для загрузки существующей схемы psql с помощью столбца XML и посмотреть, как ее обрабатывает грамотно sqlalchemy. Но даже в лучшем случае я не думаю, что вы получите хорошие вещи, такие как индексирование XPATH, даже если отражение действительно делает что-то изящное, как выставляя столбец как тип текста. Попробуйте подать запрос на повышение в трекер-вопроснике sqlalchemy. – JosefAssad

+0

Посмотрите также пример использования zzzeek для использования списка смежности для хранения данных XML: https://bitbucket.org/sqlalchemy/sqlalchemy/src/2a4318815eb13a8d9f58bcf7009b115f2c8a839d/examples/elementtree/optimized_al.py?at=default – JosefAssad

+0

мы стараемся полагаться на psycopg2, насколько это возможно для этих типов, в то время как они поддерживают JSON и HSTORE, у них нет типа XML: http://initd.org/psycopg/docs/extras.html#additional-data-types. что вы все еще можете получить много функциональности здесь, используя techinques по адресу http://docs.sqlalchemy.org/en/rel_0_8/core/types.html#types-custom, и мы, конечно же, будем принимать запросы на получение завершенного кода. – zzzeek

ответ

0

См: SQLAlchemy TypeDecorator doesn't work

Здесь же решение модифицировано для обработки XmlType для оракула любой длиной XML и позволить LXML etree задания и из колонки класса (нет необходимости deparse/повторный обработки XML из контейнерных классов)

# coding: utf-8 
from sqlalchemy import Column, DateTime, Float, ForeignKey, Index, Numeric, String, Table, Text, CLOB 
from sqlalchemy.orm import relationship 
from sqlalchemy.ext.declarative import declarative_base 

from sqlalchemy.sql.functions import GenericFunction 
class XMLTypeFunc(GenericFunction): 
    type=CLOB 
    name='XMLType' 
    identifier='XMLTypeFunc' 


from sqlalchemy.types import TypeDecorator 
from lxml import etree #you can use built-in etree if you want 
class XMLType(TypeDecorator): 

    impl = CLOB 
    type = 'XMLTYPE' #etree.Element 

    def get_col_spec(self): 
     return 'XMLTYPE' 

    def bind_processor(self, dialect): 
     def process(value): 
      if value is not None: 
       return etree.tostring(value, encoding='UTF-8', pretty_print='True') 
       #return etree.dump(value) 
      else: 
       return None 
     return process 

    def process_result_value(self, value, dialect): 
     if value is not None: 
      value = etree.fromstring(value) 
     return value 

    def bind_expression(self, bindvalue): 
     return XMLTypeFunc(bindvalue) 
0

Если вам нужно иметь собственный тип «XML» данных в базе данных PostgreSQL, вам нужно написать специальный тип, который унаследованный от UserDefinedType не из TypeDecorator. Documentation

Вот что я использовал в одном из проектов:

class XMLType(sqlalchemy.types.UserDefinedType): 
    def get_col_spec(self): 
     return 'XML' 

    def bind_processor(self, dialect): 
     def process(value): 
      if value is not None: 
       if isinstance(value, str): 
        return value 
       else: 
        return etree.tostring(value) 
      else: 
       return None 
     return process 

    def result_processor(self, dialect, coltype): 
     def process(value): 
      if value is not None: 
       value = etree.fromstring(value) 
      return value 
     return process 
Смежные вопросы