Как напечатать все столбцы в SQLAlchemy ORM - PullRequest
12 голосов
/ 18 мая 2011

Используя SQLAlchemy, я пытаюсь распечатать все атрибуты каждой модели, которые у меня есть, аналогично:

SELECT * from table;

Однако я хотел бы что-то сделать с информацией об экземпляре каждой модели, как только получу ее. Пока лучшее, что я смог придумать, это:

for m in session.query(model).all():
    print [getattr(m, x.__str__().split('.')[1]) for x in model.__table__.columns]
    # additional code 

И это даст мне то, что я ищу, но это довольно окольный способ получить это. Я как бы надеялся на атрибут в соответствии с:

m.attributes 
# or 
m.columns.values

Я чувствую, что что-то упустил, и есть гораздо лучший способ сделать это. Я делаю это, потому что я буду печатать все в файлы .CSV, и я не хочу указывать интересующие меня столбцы / атрибуты, я хочу все (есть много столбцов в большом количестве моделей для печати).

Ответы [ 10 ]

17 голосов
/ 28 февраля 2015

Это старая запись, но я столкнулся с проблемой с фактическими именами столбцов базы данных, не соответствующими сопоставленным именам атрибутов в экземпляре.Мы закончили с этим:

from sqlalchemy import inspect
inst = inspect(model)
attr_names = [c_attr.key for c_attr in inst.mapper.column_attrs]

Надеюсь, что это поможет кому-то с такой же проблемой!

11 голосов
/ 18 марта 2014

Опираясь на ответ Родни Л:

model = MYMODEL
columns = [m.key for m in model.__table__.columns]
8 голосов
/ 19 октября 2015

Вероятно, самое короткое решение (см. Недавнюю документацию ):

from sqlalchemy.inspection import inspect
table = inspect(model)
for column in table.c
    print column.name
5 голосов
/ 21 сентября 2012

Я считаю, что это самый простой способ:

print [cname for cname in m.__dict__.keys()]

РЕДАКТИРОВАТЬ: ответ выше меня, используя sqlalchemy.inspection.inspect (), кажется, лучшее решение.

4 голосов
/ 18 мая 2011

Взгляните на функцию отражения метаданных SQLAchemy .

2 голосов
/ 28 сентября 2017
print repr(model.__table__)

Или только столбцы:

print str(list(model.__table__.columns))
2 голосов
/ 27 августа 2016

Я использую SQL Alchemy v 1.0.14 на Python 3.5.2

Предполагая, что вы можете подключиться к движку с помощью create_engine (), я смог отобразить все столбцы, используя следующий код. Замените «строку подключения» и «имя моей таблицы» соответствующими значениями.

from sqlalchemy import create_engine, MetaData, Table, select

engine = create_engine('my connection string')

conn = engine.connect()
metadata = MetaData(conn)
t = Table("my table name", metadata, autoload=True)
columns = [m.key for m in t.columns]
columns

в последней строке просто отображаются имена столбцов из предыдущего оператора.

2 голосов
/ 03 августа 2015

Сложите это воедино и найдите это полезным:

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
engine = create_engine('mysql+pymysql://testuser:password@localhost:3306/testdb')
DeclarativeBase = declarative_base()
metadata = DeclarativeBase.metadata
metadata.bind = engine


# configure Session class with desired options
Session = sessionmaker()

# associate it with our custom Session class
Session.configure(bind=engine)

# work with the session
session = Session()

А затем:

d = {k: metadata.tables[k].columns.keys() for k in metadata.tables.keys()}

Пример вывода print(d):

{'orderdetails': ['orderNumber', 'productCode', 'quantityOrdered', 'priceEach', 'orderLineNumber'], 
'offices': ['addressLine1', 'addressLine2', 'city', 'country', 'officeCode', 'phone', 'postalCode', 'state', 'territory'],
'orders': ['comments', 'customerNumber', 'orderDate', 'orderNumber', 'requiredDate', 'shippedDate', 'status'],
'products': ['MSRP', 'buyPrice', 'productCode', 'productDescription', 'productLine', 'productName', 'productScale', 'productVendor', 'quantityInStock'],
'employees': ['employeeNumber', 'lastName', 'firstName', 'extension', 'email', 'officeCode', 'reportsTo', 'jobTitle'], 
'customers': ['addressLine1', 'addressLine2', 'city', 'contactFirstName', 'contactLastName', 'country', 'creditLimit', 'customerName', 'customerNumber', 'phone', 'postalCode', 'salesRepEmployeeNumber', 'state'],
'productlines': ['htmlDescription', 'image', 'productLine', 'textDescription'],
'payments': ['amount', 'checkNumber', 'customerNumber', 'paymentDate']}

ИЛИ:

from sqlalchemy.sql import text
cmd = "SELECT * FROM information_schema.columns WHERE table_schema = :db ORDER BY table_name,ordinal_position"
result = session.execute(
            text(cmd),
            {"db": "classicmodels"}
        )
result.fetchall()
1 голос
/ 18 мая 2011

Вас может заинтересовать то, что я придумал, чтобы сделать это.

from sqlalchemy.orm import class_mapper
import collections

# structure returned by get_metadata function.
MetaDataTuple = collections.namedtuple("MetaDataTuple", 
        "coltype, colname, default, m2m, nullable, uselist, collection")


def get_metadata_iterator(class_):
    for prop in class_mapper(class_).iterate_properties:
        name = prop.key
        if name.startswith("_") or name == "id" or name.endswith("_id"):
            continue
        md = _get_column_metadata(prop)
        if md is None:
            continue
        yield md


def get_column_metadata(class_, colname):
    prop = class_mapper(class_).get_property(colname)
    md = _get_column_metadata(prop)
    if md is None:
        raise ValueError("Not a column name: %r." % (colname,))
    return md


def _get_column_metadata(prop):
    name = prop.key
    m2m = False
    default = None
    nullable = None
    uselist = False
    collection = None
    proptype = type(prop)
    if proptype is ColumnProperty:
        coltype = type(prop.columns[0].type).__name__
        try:
            default = prop.columns[0].default
        except AttributeError:
            default = None
        else:
            if default is not None:
                default = default.arg(None)
        nullable = prop.columns[0].nullable
    elif proptype is RelationshipProperty:
        coltype = RelationshipProperty.__name__
        m2m = prop.secondary is not None
        nullable = prop.local_side[0].nullable
        uselist = prop.uselist
        if prop.collection_class is not None:
            collection = type(prop.collection_class()).__name__
        else:
            collection = "list"
    else:
        return None
    return MetaDataTuple(coltype, str(name), default, m2m, nullable, uselist, collection)
0 голосов
/ 03 октября 2013

Я использую это, потому что это немного короче:

for m in session.query(*model.__table__.columns).all():
    print m
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...