2013-04-22 62 views
3

SqlAlchemy通過方言支持大多數數據庫特定的數據類型,但是我找不到任何與postgresql xml列類型一起工作的東西。有人知道一個可行的解決方案嗎?理想情況下,我自己不應該需要自定義列類型實現。在sqlalchemy中使用postgresql xml數據類型

+0

我沒有看到它在PostgreSQL的方言實施與SQLAlchemy的0.8。您可以嘗試使用反射來加載現有的psql模式和XML列,並查看sqlalchemy如何優雅地處理它。但即使是在最好的情況下,我認爲即使反射確實做了一些優雅的事情,例如將列作爲文本類型公開,也不會像XPATH索引那樣獲得很好的效果。嘗試在sqlalchemy問題跟蹤器中提交增強請求。 – JosefAssad 2013-04-22 18:50:08

+0

也看看zzzeek使用鄰接表來存儲XML數據的例子:https://bitbucket.org/sqlalchemy/sqlalchemy/src/2a4318815eb13a8d9f58bcf7009b115f2c8a839d/examples/elementtree/optimized_al.py?at=default – JosefAssad 2013-04-22 19:00:31

+0

我們試圖依靠在psycopg2儘可能多的這些類型,雖然他們支持JSON和HSTORE他們沒有XML類型:http://initd.org/psycopg/docs/extras.html#additional-data-types。也就是說你仍然可以在http://docs.sqlalchemy.org/en/rel_0_8/core/types.html#types-custom使用techinques獲得很多功能,我們當然會接受完成代碼的pull請求。 – zzzeek 2013-04-23 23:28:06

回答

0

參見:SQLAlchemy TypeDecorator doesn't work

這裏是修改,以處理用於Oracle 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

如果您需要在PostgreSQL數據庫原生「XML」數據類型,你需要寫從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