I have a database with a table named "items":
import sqlite3
stmt = """CREATE TABLE items (id INTEGER PRIMARY KEY, name TEXT)"""
conn = sqlite3.connect('test20210101.db')
conn.execute(stmt)
I use SQLAlchemy's automap feature to map the table to a model class:
import sqlalchemy as sa
from sqlalchemy.ext.automap import automap_base
engine = sa.create_engine('sqlite:///test20210101.db')
Base = automap_base()
Base.prepare(engine, reflect=True)
Item = Base.classes.items
However if I try to create a new item, I get a TypeError
:
>>> new_item = Item(name='foo')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: items() got an unexpected keyword argument 'name'
Likewise attempts to query the database using the automapped model fail:
>>> items = session.query(Item).all()
Traceback (most recent call last):
<lots of traceback>
sqlalchemy.exc.ArgumentError: Column expression or FROM clause expected, got ('items', <class 'sqlalchemy.ext.automap.items'>).
Similar code works for other tables, what's going on here?
As the raising of TypeError
suggests, the problem is that Item
is not an automapped model as we would expect. In fact it's a method object:
>>> type(Item)
<class 'method'>
>>> Item
<bound method Properties.items of <sqlalchemy.util._collections.Properties object at 0x7fb088f48fa0>>
The problem is that Base.classes
exposes a dictionary-like API, and Base.classes.items
is the API's items
method rather than the automapped object*.
There are at least two ways to work around this name collision:
access the automapped object using __getitem__
>>> Item = Base.classes['items'] >>> Item <class 'sqlalchemy.ext.automap.items'>
define a custom function to map table names to class names when preparing the Base
>>> def map_names(base, tablename, table): ... return 'my_items' if tablename == 'items' else tablename... >>> Base = automap_base() >>> Base.prepare(engine, reflect=True, classname_for_table=map_names) >>> Item = Base.classes.my_items >>> Item <class 'sqlalchemy.ext.automap.my_items'>
* So the same problem occurs for other dict-related names, for example keys
, values
etc.
You are importing the file not the class Item
change:
import Item
to
from Item import Item
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.