Reputation: 36247
I have created a tmp table from a sqllite table which is a subset of the original table based on various selection criteria. A sample is in the screenshot.
I'm trying to loop through the table records one at a time in order to update a field in each. I have run into a problem detailed in Mapper could not assemble any primary key columns . Based on the recommendations at http://docs.sqlalchemy.org/en/latest/faq/ormconfiguration.html#how-do-i-map-a-table-that-has-no-primary-key . Based on this discussion I do have a candidate key which is a unique id : the column 'id'. Therefore, I have changed my code to:
source_table= self.source
engine = create_engine(db_path)
Base = declarative_base()
# metadata = Base.metadata
# Look up the existing tables from database
Base.metadata.reflect(engine)
# Create class that maps via ORM to the database table
table = type(source_table, (Base,), {'__tablename__': source_table}, __mapper_args__ = {
'primary_key':'id'
})
Session = sessionmaker(bind=engine)
session = Session()
i = 0
for row in session.query(table).limit(500):
i += 1
print object_as_dict(row)
But this gives:
TypeError: type() takes 1 or 3 arguments
How can I use the mapper_args argument to identify id as the primary key
edit:
I tried :
table = type(source_table, (Base,), {'__tablename__': source_table}, {"__mapper_args__": {"primary_key": [Base.metadata.tables[source_table].c.id]}})
giving:
TypeError: type() takes 1 or 3 arguments
Upvotes: 0
Views: 634
Reputation: 20518
__mapper_args__
needs to be an attribute defined on the class. Whereas you need to write
class Foo(Base):
...
__mapper_args__ = {...}
when defining a class with the class
syntax, you need to write
type("Foo", (Base,), {..., "__mapper_args__": {...}})
when defining a class with the type
function.
Note that __mapper_args__
may need to be
{"primary_key": [Base.metadata.tables[source_table].c.id]}
instead of
{"primary_key": "id"}
for it to work properly.
Upvotes: 2