I'm following the sqlalchemy documentation for reflecting database tables using automap
: http://docs.sqlalchemy.org/en/latest/orm/extensions/automap.html#generating-mappings-from-an-existing-metadata.
When I don't specific a schema, and Postgres uses the default public
schema, this works as expected, and I find the names of my tables:
>>> m = MetaData()
>>> b = automap_base(bind=engine, metadata=m)
>>> b.prepare(engine, reflect=True)
>>> b.classes.keys()
['ads', 'spatial_ref_sys', 'income']
But when I specific an explicit schema, I don't have access to the tables in Base.classes
anymore.
>>> m = MetaData(schema='geography')
>>> b = automap_base(bind=engine, metadata=m)
>>> b.prepare(engine, reflect=True)
>>> b.classes.keys()
[]
The MetaData reflected correctly though:
>>> b.metadata.tables
immutabledict({geography.usa_cbsa_centroids': Table('usa_cbsa_centroids', MetaData(bind=Engine(postgresql://asteroids:***@localhost:5432/asteroids)), Column('GEOID', VARCHAR(length=5), table=<u
sa_cbsa_centroids>, nullable=False), ...})
Note that the tables and columns are only known at runtime.
Define an extension to the sqlalchemy. ext. declarative system which automatically generates mapped classes and relationships from a database schema, typically though not necessarily one which is reflected.
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.
from sqlalchemy import MetaData metadata_obj = MetaData() MetaData is a container object that keeps together many different features of a database (or multiple databases) being described. To represent a table, use the Table class.
This section references SQLAlchemy schema metadata, a comprehensive system of describing and inspecting database schemas. The core of SQLAlchemy's query and object mapping operations are supported by database metadata, which is comprised of Python objects that describe tables and other schema-level objects.
The answer is that database tables in SQLAlchemy require a primary key, and my table didn't have one. There is additional information on this page: http://docs.sqlalchemy.org/en/latest/faq/ormconfiguration.html#how-do-i-map-a-table-that-has-no-primary-key.
The SQLAlchemy ORM, in order to map to a particular table, needs there to be at least one column denoted as a primary key column; multiple-column, i.e. composite, primary keys are of course entirely feasible as well. These columns do not need to be actually known to the database as primary key columns, though it’s a good idea that they are. It’s only necessary that the columns behave as a primary key does, e.g. as a unique and not nullable identifier for a row.
Thanks to Michael Bayer for answering this on the sqlalchemy mailing list: https://groups.google.com/forum/#!topic/sqlalchemy/8F2tPkpR4bE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With