user1592380
user1592380

Reputation: 36247

Creating a primary key in sqlalchemy when creating a table instance

enter image description here

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

Answers (1)

univerio
univerio

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

Related Questions