SQLAlchemy 不创建表
SQLAlchemy not creating tables
我正在尝试像在教程中那样设置数据库,但是当我尝试添加 User
[= 时,出现了一个编程错误,提示 table 不存在19=]
这是错误的文件 (database.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()
要初始化数据库(创建 tables)我只是 运行 文件。
创建测试用户时出错。
这里是models.py
:
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)
我试过了:
- 在添加用户之前提交(在
create_all
之后)
- 从数据库中删除现有的 table(尽管 table 似乎永远不会被提交)
from models import User
而不是 import models
(在 create_all
之前)
抱歉,如果有这么多类似的问题,我保证我已经搜索过答案,但我确保我没有犯(或至少我看到的那些)总是愚蠢的错误。
我正在使用 MariaDB。
很抱歉post,非常感谢。
database.py
中的 Base
与导入 models.py
的 Base
不同。
一个简单的测试是在 Base = declarative_base()
语句的正上方放置一个 print('creating Base')
函数调用,您会看到它被创建了两次。
Python 调用正在执行的模块 '__main__'
,因为模块底部有 if __name__ == '__main__'
条件。所以创建的第一个 Base
是 __main__.Base
。然后,在 models.py
中,from database import Base
导致 database
模块再次被解析,在命名空间中创建 database.Base
,也就是 Base
来自 User
继承。然后回到 database.py
,Base.metadata.create_all(bind=engine)
调用正在使用来自 __main__.Base
的元数据,其中没有表,因此不会创建任何内容。
不要执行创建 Base
实例的模块。创建另一个名为 main.py
(或其他)的模块,然后将 init_db()
函数移到那里并将 Base
、db_session
和 engine
从 database.py
导入到main.py
。这样,您始终使用相同的 Base
实例。这是 main.py
:
的例子
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 class 一次(对于每个数据库)并将其导入到定义 table classes(继承自 Base)的所有模块
- 为了使 Base (a metaclass) 扫描并找出所有继承自它的 classes,我们需要导入所有模块,其中 table classes(继承自 Base)被定义到我们调用 Metadata.create_all(engine).
的模块
我正在尝试像在教程中那样设置数据库,但是当我尝试添加 User
[= 时,出现了一个编程错误,提示 table 不存在19=]
这是错误的文件 (database.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()
要初始化数据库(创建 tables)我只是 运行 文件。 创建测试用户时出错。
这里是models.py
:
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)
我试过了:
- 在添加用户之前提交(在
create_all
之后) - 从数据库中删除现有的 table(尽管 table 似乎永远不会被提交)
from models import User
而不是import models
(在create_all
之前)
抱歉,如果有这么多类似的问题,我保证我已经搜索过答案,但我确保我没有犯(或至少我看到的那些)总是愚蠢的错误。
我正在使用 MariaDB。
很抱歉post,非常感谢。
database.py
中的 Base
与导入 models.py
的 Base
不同。
一个简单的测试是在 Base = declarative_base()
语句的正上方放置一个 print('creating Base')
函数调用,您会看到它被创建了两次。
Python 调用正在执行的模块 '__main__'
,因为模块底部有 if __name__ == '__main__'
条件。所以创建的第一个 Base
是 __main__.Base
。然后,在 models.py
中,from database import Base
导致 database
模块再次被解析,在命名空间中创建 database.Base
,也就是 Base
来自 User
继承。然后回到 database.py
,Base.metadata.create_all(bind=engine)
调用正在使用来自 __main__.Base
的元数据,其中没有表,因此不会创建任何内容。
不要执行创建 Base
实例的模块。创建另一个名为 main.py
(或其他)的模块,然后将 init_db()
函数移到那里并将 Base
、db_session
和 engine
从 database.py
导入到main.py
。这样,您始终使用相同的 Base
实例。这是 main.py
:
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 class 一次(对于每个数据库)并将其导入到定义 table classes(继承自 Base)的所有模块
- 为了使 Base (a metaclass) 扫描并找出所有继承自它的 classes,我们需要导入所有模块,其中 table classes(继承自 Base)被定义到我们调用 Metadata.create_all(engine). 的模块