簡體   English   中英

SQLAlchemy-如何從ResultProxy訪問列名並寫入CSV標頭

[英]SQLAlchemy - How to access column names from ResultProxy and write to CSV headers

我正在嘗試使用SQLAlchemy建立與PostgreSQL數據庫的連接,執行SQL查詢並將文件的輸出打印到Linux中的文件。

from sqlalchemy import create_engine
import yaml
import csv

outfile = open('/path/filename.csv', 'wb')
outcsv = csv.writer(outfile, delimiter='\t')


with open('config.yml') as f:
    cfg = yaml.safe_load(f)
    username = cfg['credentials']['username']
    password = cfg['credentials']['password']
    host = cfg['credentials']['host'] 
    port = cfg['credentials']['port']
    dbname = cfg['credentials']['dbname']
    engine = create_engine('postgresql://{}:{}@{}:{}/{}'.format(username, password, host, port, dbname))
    result = engine.execute("""select * from db.tablename """)

    # dump column titles (optional)
    outcsv.writerow(x[0] for x in result.description)

    # dump rows
    outcsv.writerows(result.fetchall())
    outfile.close()

但是,我收到以下錯誤消息-Traceback(最近一次調用): AttributeError中的文件“”,第12行:“ ResultProxy”對象沒有屬性“ description”

如果注釋以下命令,則可以成功獲取查詢結果,但沒有標題。 outcsv.writerow(x [0]對於x在result.description中)

經過研究,我發現方法-result._metadata.keys可以生成標頭。 但是,它以某種形式生成列表,我無法將其附加為標題。

請告知是否有任何方法可以將文件頭以及數據獲取到csv文件中。 在回答以上問題時,請考慮我是Python的初學者的事實。

在示例的這一行中:

result = engine.execute("""select * from db.tablename """)

變量result指向類sqlalchemy.engine.ResultProxy的實例。

您想要獲取列名稱以寫入到csv文件的第一行,並通過檢查result對象找到result._metadata.keys來返回常規的python列名稱list

Python中的一個約定是,只要對象的屬性,變量或方法前面帶有下划線(例如_metadata ),這意味着它不打算成為公共API,並且程序包的維護者可以以這種方式更改其實現。如果您依賴這些東西,則會破壞您的代碼(但是,對於穩定的庫(如SQLAlchemy)來說不太可能)。 幸運的是,在這種情況下,有一個文檔化的公共API供您獲取所需的內容: ResultProxy.keys()

請記住,您的result變量指向ResultProxy實例,因此您可以訪問該實例上的keys()方法以獲取列名,例如:

result.keys()

當我們嘗試寫入您的csv文件時會發生什么:

outcsv.writerow(result.keys())

我們得到以下異常:

TypeError: a bytes-like object is required, not 'str'

我將假設您在說這句話時指的是:

但是,它以某種形式生成列表,我無法將其附加為標題。

您可以看一下open() API,但是問題在於您以一種期望二進制數據的方式打開了文件,而不是從result.keys()返回的字符串。 因此,如果我們將打開文件的行更改為:

outfile = open('/path/filename.csv', 'w')

outfile.writerow將接受result.keys()的結果。

其他一切都應該“正常工作”。

這是我用來測試的代碼:

import csv

from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()
engine = create_engine('sqlite:///:memory:', echo=False)
Session = sessionmaker(bind=engine)

class Model(Base):
    __tablename__ = 'model'
    id = Column(Integer, primary_key=True)
    col1 = Column(String(10))
    col2 = Column(String(10))

if __name__ == '__main__':
    # create some test data
    Base.metadata.drop_all(bind=engine)
    Base.metadata.create_all(bind=engine)
    s = Session()
    data = dict(col1='a', col2='b')
    s.add_all(Model(**data) for _ in range(5))
    s.commit()
    s.close()
    # put the session away and work with the engine

    result = engine.execute("select * from model")

    outfile = open('filename.csv', 'w', newline='')
    outcsv = csv.writer(outfile, delimiter='\t')
    outcsv.writerow(result.keys())
    outcsv.writerows(result.fetchall())

這是csv的內容:

id  col1    col2
1   a   b
2   a   b
3   a   b
4   a   b
5   a   b

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM