我正在将Python Sqlalchemy用于MYSQL数据库。我编写了以下脚本来创建类对象,然后在表中添加一行。
from sqlalchemy import create_engine, MetaData, Table, Column, ForeignKey
from sqlalchemy.dialects.mysql.base import VARCHAR, LONGTEXT, INTEGER
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine("mysql+mysqldb://root:@localhost/mydb")
connection = engine.connect()
Session = sessionmaker(bind=engine)
session = Session()
Base = declarative_base()
metadata = MetaData()
class User(Base):
__tablename__ = 'User'
__abstract__ = True
id = Column('id', INTEGER(display_width=11), primary_key=True, nullable=False)
email = Column('email', VARCHAR(charset='utf8mb4', collation='utf8mb4_0900_ai_ci', length=100), unique=True)
password = Column('password', VARCHAR(charset='utf8mb4', collation='utf8mb4_0900_ai_ci', length=45))
name = Column('name', VARCHAR(charset='utf8mb4', collation='utf8mb4_0900_ai_ci', length=100))
Base.metadata.create_all(engine)
add_user = User(email = "testing@testing.com",
password = 'testing',
name = 'testing')
session.add(add_user)
session.commit()
当我尝试添加到会话时,它引发以下错误:
AttributeError: 'User' object has no attribute '_sa_instance_state'
During handling of the above exception, another exception occurred:
raise exc.UnmappedInstanceError(instance)
sqlalchemy.orm.exc.UnmappedInstanceError: Class '__main__.User' is not mapped
我是SQLalchemy和OOP的新手,所以无法弄清楚我在做什么错。任何帮助将不胜感激
答案 0 :(得分:1)
问题源于在__abstract__ == True
上定义User
。
来自docs:
__abstract__
使声明式完全跳过该类的表或映射器的生成。可以在层次结构中添加类 以与mixin相同的方式(请参见Mixin和自定义基类),允许 子类仅从特殊类扩展而来
如果您将User
抽象,要进行映射,则需要使用其他模型将其子类化,例如这有效:
class User(Base):
__tablename__ = 'User'
__abstract__ = True
id = Column('id', INTEGER(display_width=11), primary_key=True, nullable=False)
email = Column('email', VARCHAR(charset='utf8mb4', collation='utf8mb4_0900_ai_ci', length=100), unique=True)
password = Column('password', VARCHAR(charset='utf8mb4', collation='utf8mb4_0900_ai_ci', length=45))
name = Column('name', VARCHAR(charset='utf8mb4', collation='utf8mb4_0900_ai_ci', length=100))
class AUser(User):
pass
if __name__ == '__main__':
Base.metadata.create_all(bind=engine)
add_user = AUser(email = "testing@testing.com",
password = 'testing',
name = 'testing')
session.add(add_user)
session.commit()