繁体   English   中英

SQLAlchemy 从 create() 打印原始 SQL

[英]SQLAlchemy printing raw SQL from create()

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

from sqlalchemy.schema import CreateTable

print(CreateTable(table))

如果您使用声明式语法:

print(CreateTable(Model.__table__))

更新:

由于我已经接受了答案并且klenwell answer 中有重要信息,我也会在这里添加它。

您可以通过使用引擎进行编译来获取特定数据库(MySQL、Postgresql 等)的 SQL。

print(CreateTable(Model.__table__).compile(engine))

更新 2:

@jackotonye 在评论中添加了一种无需引擎的方法。

print(CreateTable(Model.__table__).compile(dialect=postgresql.dialect()))

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

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))

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

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)

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

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

像这样的东西? (来自 SQLA 常见问题解答)

http://docs.sqlalchemy.org/en/latest/faq/sqlexpressions.html

事实证明这是直截了当的:

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()))

输出这个:

CREATE TABLE users (
    username VARCHAR
)

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

参考

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

...

或没有引擎:

 from sqlalchemy.dialects import postgresql print(statement.compile(dialect=postgresql.dialect()))

来源: 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})) + ';')

处理此 users.csv 时:

sAMAccountName,mail
bmcboatface,boaty.mcboatface@example.com
ndhyani,naina.dhyani@contoso.com

给出这样的输出:

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';

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

可能你的意思是 sqlalchemy.create_engine 的echo参数?

/tmp$ cat test_s.py

import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Department(Base):
    __tablename__ = "departments"

    department_id = sa.Column(sa.types.Integer, primary_key=True)
    name = sa.Column(sa.types.Unicode(100), unique=True)
    chief_id = sa.Column(sa.types.Integer)
    parent_department_id = sa.Column(sa.types.Integer,
                                     sa.ForeignKey("departments.department_id"))

    parent_department = sa.orm.relation("Department")


engine = sa.create_engine("sqlite:///:memory:", echo=True)
Base.metadata.create_all(bind=engine)

/tmp$ python test_s.py

2011-03-24 15:09:58,311 INFO sqlalchemy.engine.base.Engine.0x...42cc PRAGMA table_info("departments")
2011-03-24 15:09:58,312 INFO sqlalchemy.engine.base.Engine.0x...42cc ()
2011-03-24 15:09:58,312 INFO sqlalchemy.engine.base.Engine.0x...42cc 
CREATE TABLE departments (
    department_id INTEGER NOT NULL, 
    name VARCHAR(100), 
    chief_id INTEGER, 
    parent_department_id INTEGER, 
    PRIMARY KEY (department_id), 
    UNIQUE (name), 
    FOREIGN KEY(parent_department_id) REFERENCES departments (department_id)
)

2011-03-24 15:09:58,312 INFO sqlalchemy.engine.base.Engine.0x...42cc ()
2011-03-24 15:09:58,312 INFO sqlalchemy.engine.base.Engine.0x...42cc COMMIT

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM