Python SQLAlchemy不创建表

Python SQLAlchemy不创建表,python,sqlalchemy,Python,Sqlalchemy,我正试图像在教程中一样设置数据库,但当我试图添加用户时,我遇到了一个编程错误,即表不存在 这是出现错误的文件(database.py): 要初始化数据库(创建表),我只需运行该文件。 它在创建测试用户时出错 下面是models.py: from sqlalchemy import create_engine, MetaData from sqlalchemy.orm import scoped_session, sessionmaker from sqlalchemy.ext.declarati

我正试图像在教程中一样设置数据库,但当我试图添加
用户时,我遇到了一个编程错误,即表不存在

这是出现错误的文件(
database.py
):

要初始化数据库(创建表),我只需运行该文件。 它在创建测试用户时出错

下面是
models.py

from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base


engine = create_engine(
    "mysql+pymysql://testuser:testpassword@localhost/test?charset=utf8",
    connect_args = {
        "port": 3306
    },
    echo="debug",
    echo_pool=True
)

db_session = scoped_session(
    sessionmaker(
        bind=engine,
        autocommit=False,
        autoflush=False
    )
)

Base = declarative_base()

def init_db():
    import models
    Base.metadata.create_all(bind=engine)

    from models import User
    db_session.add(
        User(username="testuser", password_hash=b"", password_salt=b"", balance=1)
    )
    db_session.commit()

    print("Initialized the db")


if __name__ == "__main__":
    init_db()
from sqlalchemy import Column, Integer, Numeric, Binary, String
from sqlalchemy.orm import relationship

from database import Base


class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True)

    username = Column(String(16), unique=True)
    password_hash = Column(Binary(32))
    password_salt = Column(Binary(32))

    balance = Column(Numeric(precision=65, scale=8))

    def __repr__(self):
        return "<User(balance={})>".format(balance)
from database import Base, db_session, engine
from models import User


def init_db():

    Base.metadata.create_all(bind=engine)

    db_session.add(
        User(username="testuser", password_hash=b"", password_salt=b"", balance=1)
    )
    db_session.commit()

    print("Initialized the db")


if __name__ == "__main__":
    init_db()
来自sqlalchemy导入列、整数、数字、二进制、字符串
从sqlalchemy.orm导入关系
从数据库导入库
类用户(基本):
__tablename_=“用户”
id=列(整数,主键=True)
username=Column(字符串(16),unique=True)
密码\u散列=列(二进制(32))
密码\u salt=列(二进制(32))
天平=列(数字(精度=65,刻度=8))
定义报告(自我):
返回格式(余额)
我试过:

  • 在添加用户之前提交(在
    创建\u all
    之后)
  • 从数据库中删除现有表(尽管该表似乎从未提交)
  • 从模型导入用户
    而不是
    导入模型
    (在
    创建所有
    之前)
抱歉,如果有这么多类似的问题,我保证我会寻找答案,但我总是犯愚蠢的错误,确保我没有犯(或者至少是我看到的那些)

我正在使用MariaDB


很抱歉发了这么长的帖子,非常感谢。

数据库.py中的
Base
与导入到
models.py中的
Base
不同

一个简单的测试是将一个
print('creating Base')
函数调用放在
Base=declarative_Base()
语句的正上方,您将看到它被创建了两次

Python调用正在执行的模块
“\uuuuu main\uuuuu”
,您知道,如果模块底部有
条件,则该模块具有
。因此,创建的第一个
Base
\uuuuu main\uuuuu.Base
。然后,在
models.py
中,来自数据库导入库的
导致再次解析
database
模块,在名称空间中创建
database.Base
,即
Base
,用户从中继承。然后回到
database.py
Base.metadata.create\u all(bind=engine)
调用使用的是
\uuuuuu main\uuuuu.Base
中没有表的元数据,因此不会创建任何内容

不要在创建
Base
实例的模块之外执行。创建另一个名为
main.py
(或其他)的模块,将
init_db()
函数移到那里,然后从
database.py
导入
Base
db_session
engine
。这样,您总是使用相同的
Base
实例。这是
main.py
的示例:

from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base


engine = create_engine(
    "mysql+pymysql://testuser:testpassword@localhost/test?charset=utf8",
    connect_args = {
        "port": 3306
    },
    echo="debug",
    echo_pool=True
)

db_session = scoped_session(
    sessionmaker(
        bind=engine,
        autocommit=False,
        autoflush=False
    )
)

Base = declarative_base()

def init_db():
    import models
    Base.metadata.create_all(bind=engine)

    from models import User
    db_session.add(
        User(username="testuser", password_hash=b"", password_salt=b"", balance=1)
    )
    db_session.commit()

    print("Initialized the db")


if __name__ == "__main__":
    init_db()
from sqlalchemy import Column, Integer, Numeric, Binary, String
from sqlalchemy.orm import relationship

from database import Base


class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True)

    username = Column(String(16), unique=True)
    password_hash = Column(Binary(32))
    password_salt = Column(Binary(32))

    balance = Column(Numeric(precision=65, scale=8))

    def __repr__(self):
        return "<User(balance={})>".format(balance)
from database import Base, db_session, engine
from models import User


def init_db():

    Base.metadata.create_all(bind=engine)

    db_session.add(
        User(username="testuser", password_hash=b"", password_salt=b"", balance=1)
    )
    db_session.commit()

    print("Initialized the db")


if __name__ == "__main__":
    init_db()
  • 声明一次基类(对于每个数据库)&将其导入定义表类(从基类继承)的所有模块
  • 为了让Base(一个元类)扫描并找出从中继承的所有类,我们需要将定义此类表类(从Base继承)的所有模块导入到我们称之为Metadata.create_all(引擎)的模块中