SQLAlchemy从create()打印原始SQL

Mad*_*sen 40 python pylons sqlalchemy

我正在尝试使用SQLAlchemy进行Pylons,我喜欢它,只有一件事,是否可以在执行之前打印出从Table().create()生成的原始SQL CREATE TABLE数据?

Ant*_*air 87

from sqlalchemy.schema import CreateTable

print(CreateTable(table))
Run Code Online (Sandbox Code Playgroud)

如果您使用声明性语法:

print(CreateTable(Model.__table__))
Run Code Online (Sandbox Code Playgroud)

更新:

由于我已经接受了答案并且klenwell答案中有重要信息,我也会在此处添加.

您可以通过编译引擎来获取特定数据库(MySQL,Postgresql等)的SQL.

print(CreateTable(Model.__table__).compile(engine))
Run Code Online (Sandbox Code Playgroud)

更新2:

@jackotonye在评论中添加了一种没有引擎的方法.

print(CreateTable(Model.__table__).compile(dialect=postgresql.dialect()))
Run Code Online (Sandbox Code Playgroud)

  • 这也可以在没有引擎`print(CreateTable(Model .__ table __).compile(dialect = postgresql.dialect()))的情况下完成. (3认同)

kle*_*ell 14

我需要获取原始表sql以便为某些现有模型设置测试.这是我为SQLAlchemy 0.7.4创建的一个成功的单元测试,基于Antoine的答案作为概念证明:

from sqlalchemy import create_engine
from sqlalchemy.schema import CreateTable
from model import Foo

sql_url = "sqlite:///:memory:"    
db_engine = create_engine(sql_url)

table_sql = CreateTable(Foo.table).compile(db_engine)
self.assertTrue("CREATE TABLE foos" in str(table_sql))
Run Code Online (Sandbox Code Playgroud)


Lar*_*ars 10

您可以使用以下命令设置引擎以转储元数据创建序列:

def metadata_dump(sql, *multiparams, **params):
    # print or write to log or file etc
    print(sql.compile(dialect=engine.dialect))

engine = create_engine(myDatabaseURL, strategy='mock', executor=metadata_dump)
metadata.create_all(engine)
Run Code Online (Sandbox Code Playgroud)

这种方法的一个优点是枚举和索引包含在打印输出中.使用CreateTable离开这个.

另一个优点是模式定义的顺序是正确的并且(几乎)可用作脚本.

  • 如果您使用的 RDBMS 需要分号,请将函数体替换为这个 `print(str(sql.compile(dialect=engine.dialect)) + ";")` 以获取输出中的分号。 (2认同)

Ala*_*Dea 5

事实证明这很简单:

from sqlalchemy.dialects import postgresql
from sqlalchemy.schema import CreateTable
from sqlalchemy import Table, Column, String, MetaData

metadata = MetaData()

users = Table('users', metadata,
              Column('username', String)
)

statement = CreateTable(users)

print(statement.compile(dialect=postgresql.dialect()))
Run Code Online (Sandbox Code Playgroud)

输出此:

CREATE TABLE users (
    username VARCHAR
)
Run Code Online (Sandbox Code Playgroud)

更进一步,它甚至可以在准备好的语句中支持绑定参数。

参考

如何将SQL表达式呈现为字符串,可能带有内联的绑定参数?

...

或没有引擎:

from sqlalchemy.dialects import postgresql
print(statement.compile(dialect=postgresql.dialect()))
Run Code Online (Sandbox Code Playgroud)

消息来源:http : //docs.sqlalchemy.org/en/latest/faq/sqlexpressions.html#faq-sql-expression-string

示例:使用SQL Alchemy生成用户重命名脚本

#!/usr/bin/env python
import csv
from sqlalchemy.dialects import postgresql
from sqlalchemy import bindparam, Table, Column, String, MetaData

metadata = MetaData()

users = Table('users', metadata,
              Column('username', String)
)

renames = []

with open('users.csv') as csvfile:
    for row in csv.DictReader(csvfile):
        renames.append({
            'from': row['sAMAccountName'],
            'to': row['mail']
        })

for rename in renames:
    stmt = (users.update()
            .where(users.c.username == rename['from'])
            .values(username=rename['to']))
    print(str(stmt.compile(dialect=postgresql.dialect(),
                           compile_kwargs={"literal_binds": True})) + ';')
Run Code Online (Sandbox Code Playgroud)

处理此users.csv时:

sAMAccountName,mail
bmcboatface,boaty.mcboatface@example.com
ndhyani,naina.dhyani@contoso.com
Run Code Online (Sandbox Code Playgroud)

给出这样的输出:

UPDATE users SET username='boaty.mcboatface@example.com' WHERE users.username = 'bmcboatface';
UPDATE users SET username='naina.dhyani@contoso.com' WHERE users.username = 'ndhyani';users.username = 'ndhyani';
Run Code Online (Sandbox Code Playgroud)

为什么研究船具有电子邮件地址尚待确定。我一直与Example Inc的IT团队联系,但没有任何回应。