1

I am trying to dynamically access the list of columns for a table that I have created with SQL Alchemy. I created the table like this:

base.py

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker
import os

# Create database engine
db_name = 'database.db'
db_path = os.path.join(os.path.dirname(__file__), db_name)
db_uri = 'sqlite:///{}'.format(db_path)
engine = create_engine(db_uri, convert_unicode=True)

# Declarative base model to create database tables and classes
Base = declarative_base()
Base.metadata.bind = engine  # Bind engine to metadata of the base class

# Create database session object
db_session = scoped_session(sessionmaker(bind=engine, expire_on_commit=False))
Base.query = db_session.query_property()  # Used by graphql to execute queries

model_planet.py

from .base import Base
from .model_people import ModelPeople
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import relationship


class ModelPlanet(Base):
    """Planet model."""

    __tablename__ = 'planet'

    id = Column('id', Integer, primary_key=True)
    name = Column('name', String, doc="Name of the planet.")
    rotation_period = Column('rotation_period', String, doc="Rotation period of the planet.")
    orbital_period = Column('orbital_period', String, doc="Orbital period of the planet.")
    diameter = Column('diameter', String, doc="Diameter of the planet.")
    climate = Column('climate', String, doc="Climate period of the planet.")
    gravity = Column('gravity', String, doc="Gravity of the planet.")
    terrain = Column('terrain', String, doc="Terrain of the planet.")
    surface_water = Column('surface_water', String, doc="Surface water of the planet.")
    population = Column('population', String, doc="Population of the planet.")
    created = Column('created', String, doc="Record created date.")
    edited = Column('edited', String, doc="Record last updated date.")
    url = Column('url', String, doc="URL of the planet in the Star Wars API.")

    peopleList = relationship(ModelPeople, backref='planet')

In another file, I am importing model_planet.ModelPlanet and try to access its columns as per the documentation here: http://docs.sqlalchemy.org/en/latest/core/metadata.html

from database.model_planet import ModelPlanet

print(type(ModelPlanet))
for column in ModelPlanet.columns:
    print(column)

I get the following:

<class 'sqlalchemy.ext.declarative.api.DeclarativeMeta'>
Traceback (most recent call last):
[...]
    for column in ModelPlanet.columns:
AttributeError: type object 'ModelPlanet' has no attribute 'columns'

I guess it has to do with the way I have defined my table. How could I access its columns dynamically?

Thanks

Alexis.Rolland
  • 5,724
  • 6
  • 50
  • 77
  • 1
    `ModelPlanet` is not a table, but a mapped class, so that's probably the source of confusion. On the other hand you've linked to Core docs, but you're using ORM constructs. – Ilja Everilä Feb 15 '18 at 14:20
  • Related: https://stackoverflow.com/questions/18182319/sqlalchemy-show-me-that-attributeerror-type-object-user-has-no-attribute-co, https://stackoverflow.com/questions/2537471/method-of-iterating-over-sqlalchemy-models-defined-columns – Ilja Everilä Feb 15 '18 at 14:23

1 Answers1

3

You need to get access like this:

for column in ModelPlanet.__table__.columns:
    print(column)
Igor Lavrynenko
  • 171
  • 2
  • 13
  • 1
    Thank you it works. Could you please describe why I needed to add `__table__`? I found SQLAlchemy documentation particularly convoluted... I'm having a very hard time putting it in practice in real life scenario – Alexis.Rolland Feb 15 '18 at 11:08
  • maybe this will help - http://docs.sqlalchemy.org/en/latest/orm/extensions/declarative/table_config.html – Igor Lavrynenko Feb 15 '18 at 11:16
  • Hmm not really but thanks for sharing anyway. Like I said, their doc is pretty obscure to me. – Alexis.Rolland Feb 15 '18 at 11:26