2013-06-01 55 views
1

在MS Windows上,使用Python 3的pyodbc模块,我正在使用PostgreSQL。当我使用PostgreSQL的TEXT数据类型并尝试存储类UNIX的EOL时,原始\n被替换为\r\n。看下面的例子。PostgreSQL在文本字段中使用Python替换LF + CR + LF pyodbc

import pyodbc 

def main(): 

    connection = pyodbc.connect(
        'DRIVER={PostgreSQL Unicode(x64)};' 
        'SERVER=127.0.0.1;' 
        'UID=postgres;' 
        'PWD=topsecret;' 
        'DATABASE=db1'); 
    cursor = connection.cursor(); 

    cursor.execute('CREATE SCHEMA schema1 ' 
        'CREATE TABLE table1 (' 
         'key SERIAL PRIMARY KEY,' 
         'value TEXT' 
        ')'); 

    cursor.execute('INSERT INTO schema1.table1 (value) VALUES (?)', 
        'hello\nworld'); 

    r = cursor.execute('SELECT value FROM schema1.table1').fetchone()[0]; 

    print(r == 'hello\nworld'); # prints False 

    print(r == 'hello\r\nworld'); # prints True 


if __name__ == '__main__': 
    main(); 

确实,这种行为在某些情况下可能是有利的。但是,就我而言,这是不可取的。我无法找到如何在PostgreSQL的文档中关闭此功能,并且我不确定替换是在哪里发生的。有任何想法吗?

+1

为什么使用'pyodbc'而不是比较高级的'psycopg2'? –

+2

另外,我会说转换可能是在ODBC驱动程序。检查DSN设置页面。 –

+0

@CraigRinger你是对的,我只是尝试过''psycopg2''而不是''pyodbc'',LF→CR + LF不再发生。它真的在司机之内。 – Tregoreg

回答

2

很可能它是ODBC驱动程序的行为,而不是它的Python接口。也就是说,使用psycopg2几乎肯定会更好,这会更简单,更强大,更快速。

就像psqlODBCpsycopg2包装libpq但它没有笨重的ODBC中间层。

+0

我刚刚发布了根据您的建议发现的配置窗口的屏幕截图。然而,你说得对,''pyodbc''可能是个奇怪的选择。我会重构我的代码并切换到''psycopg2'',尽管我的代码大小为30 kB :-( – Tregoreg

+0

好极了!我做了一些正则表达式/手动重构并完全切换到“psycopg2”。所有的单元测试似乎现在工作得很好:-) – Tregoreg

+0

@Tregoreg很高兴听到您的声音,并感谢您在psqlODBC中为它准确配置选项。我使用的是Fedora 18而不是Windows,因此我很难找到它;-) –

1

基于@ CraigRinger的提示,我已经能够使用%windir%\system32\odbcad32.exe添加新的DSN,PostgreSQL35W。该配置允许我们在下面的截图如图所示关闭LF↔CR/LF转换:

Options page for PostgreSQL DNS

DSN=PostgreSQL35W使用代替DRIVER={PostgreSQL Unicode(x64)}固定的问题。