Sqlalchemy如果表不存在

jak*_*ong 28 python sqlalchemy

我写了一个模块来创建一个空的数据库文件

def create_database():
    engine = create_engine("sqlite:///myexample.db", echo=True)
    metadata = MetaData(engine)
    metadata.create_all()
Run Code Online (Sandbox Code Playgroud)

但是在另一个函数中,我想打开myexample.db数据库,如果它还没有该表,则创建表.

我将创建的第一个后续表的EG将是:

Table(Variable_TableName, metadata,
       Column('Id', Integer, primary_key=True, nullable=False),
       Column('Date', Date),
       Column('Volume', Float))
Run Code Online (Sandbox Code Playgroud)

(因为它最初是一个空数据库,它将没有表格,但随后,我可以添加更多表格.这就是我想说的.)

有什么建议?

jak*_*ong 46

我已经设法弄清楚我打算做什么.我曾经engine.dialect.has_table(engine, Variable_tableName)检查数据库是否包含表格.如果没有,那么它将继续在数据库中创建一个表.

示例代码:

engine = create_engine("sqlite:///myexample.db")  # Access the DB Engine
if not engine.dialect.has_table(engine, Variable_tableName):  # If table don't exist, Create.
    metadata = MetaData(engine)
    # Create a table with the appropriate Columns
    Table(Variable_tableName, metadata,
          Column('Id', Integer, primary_key=True, nullable=False), 
          Column('Date', Date), Column('Country', String),
          Column('Brand', String), Column('Price', Float),
    # Implement the creation
    metadata.create_all()
Run Code Online (Sandbox Code Playgroud)

这似乎给了我正在寻找的东西.

  • 正如 @Belle05 的回答所述,这是不必要的,因为 `create_all()` 有一个可选参数 `checkfirst`,默认为 `True`。如果设置,则仅当表尚不存在时才会创建。 (5认同)
  • 我必须在`has_table`调用中添加`schema ='dbo'`以使其在MS SQL上运行 (4认同)
  • @VIX `如果不是engine.dialect.has_table(engine, Variable_tableName, schema = 'dbo')` (2认同)

Fid*_*tix 39

接受的答案会打印一条警告,该警告engine.dialect.has_table()仅供内部使用,不属于公共 API 的一部分。该消息建议将此作为替代方案,这对我有用:

import os
import sqlalchemy

# Set up a connection to a SQLite3 DB
test_db = os.getcwd() + "/test.sqlite"
db_connection_string = "sqlite:///" + test_db
engine = create_engine(db_connection_string)

# The recommended way to check for existence
sqlalchemy.inspect(engine).has_table("BOOKS")
Run Code Online (Sandbox Code Playgroud)

另请参阅 SQL Alchemy文档

  • 是的; 这对我有用。[inspect] 返回一个布尔值,因此在所有逻辑流程中都非常易于使用。当我尝试使用 [方言] 时,我也会看到警告。 (2认同)

小智 12

请注意,在“ Base.metadata” 文档中,它声明了有关create_all的信息:

默认情况下,有条件的将不会尝试重新创建目标数据库中已经存在的表。

并且如果您可以看到create_all接受以下参数:create_all(self,bind = None,table = None,checkfirst = True),并根据文档:

默认值为True,不对目标数据库中已经存在的表发出CREATEs。

因此,如果我正确理解了您的问题,则可以跳过该条件。


Ric*_*evi 6

对于那些首先在某个models.table文件中定义表的人,以及其他表。这是一个代码片段,用于查找代表我们要创建的表的类(以便稍后我们可以使用相同的代码来查询它)

但是加上if上面写的,我还是用checkfirst=True

ORMTable.__table__.create(bind=engine, checkfirst=True)
Run Code Online (Sandbox Code Playgroud)

模型表

class TableA(Base):
class TableB(Base):
class NewTableC(Base):

   id = Column('id', Text)
   name = Column('name', Text)
Run Code Online (Sandbox Code Playgroud)

形式

然后在表单操作文件中:

engine = create_engine("sqlite:///myexample.db")
if not engine.dialect.has_table(engine, table_name):
   # Added to models.tables the new table I needed ( format Table as written above )
   table_models = importlib.import_module('models.tables')

   # Grab the class that represents the new table
   # table_name = 'NewTableC'
   ORMTable = getattr(table_models, table_name)            

   # checkfirst=True to make sure it doesn't exists
   ORMTable.__table__.create(bind=engine, checkfirst=True)
Run Code Online (Sandbox Code Playgroud)