How to print all columns in SQLAlchemy ORM

后端 未结 10 1970
再見小時候
再見小時候 2020-12-28 15:18

Using SQLAlchemy, I am trying to print out all of the attributes of each model that I have in a manner similar to:

SELECT * from table;

How

相关标签:
10条回答
  • 2020-12-28 15:22

    Take a look at SQLAchemy's metadata reflection feature.

    A Table object can be instructed to load information about itself from the corresponding database schema object already existing within the database. This process is called reflection.

    0 讨论(0)
  • 2020-12-28 15:23

    I use this because it's slightly shorter:

    for m in session.query(*model.__table__.columns).all():
        print m
    
    0 讨论(0)
  • 2020-12-28 15:29

    Put this together and found it helpful:

    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()
    

    And then:

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

    Example output 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']}
    

    OR and then:

    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()
    
    0 讨论(0)
  • 2020-12-28 15:30

    I'm using SQL Alchemy v 1.0.14 on Python 3.5.2

    Assuming you can connect to an engine with create_engine(), I was able to display all columns using the following code. Replace "my connection string" and "my table name" with the appropriate values.

    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
    

    the last row just displays the column names from the previous statement.

    0 讨论(0)
  • 2020-12-28 15:30

    You may be interested in what I came up with to do this.

    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 讨论(0)
  • 2020-12-28 15:35

    I believe this is the easiest way:

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

    EDIT: The answer above me using sqlalchemy.inspection.inspect() seems to be a better solution.

    0 讨论(0)
提交回复
热议问题