Может ли SQL Alchemy генерировать сценарий создания без его выполнения? [Дубликат]

Что было для меня целью - переустановить диспетчер пакетов NuGet, используя следующую ссылку:

VS 2013: https://github.com/NuGet/Home/releases/ загрузить / 2.8.7 / NuGet.Tools.vsix

VS 2015: https://github.com/NuGet/Home/releases/download/3.1.1/NuGet. Tools.vsix

33
задан Mads Madsen 24 January 2010 в 21:40
поделиться

6 ответов

Оказывается, это прямолинейно:

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 как строки, возможно связанные с связанными параметрами inlined?

...

или без a Двигатель:

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

Почему исследовательское судно имеет адрес электронной почты еще не определено. Я был в контакте с командой ИТ-команды примера Inc и не получил ответа.

1
ответ дан Alain O'Dea 20 August 2018 в 13:00
поделиться

Мне нужно было получить исходный стол sql для установки тестов для некоторых существующих моделей. Вот успешный модульный тест, который я создал для 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))
11
ответ дан Community 20 August 2018 в 13:00
поделиться
  • 1
    Это работает для моделей, но с отношениями «многие-ко-многим», как мне распечатывать ассоциативные таблицы, так как они также необходимы для того, чтобы вся система работала? – tchen 12 June 2014 в 19:18
  • 2
    Вы также должны объявить их. Посмотрите на doc docs.sqlalchemy.org/en/rel_0_9/orm/… . В примере с документом node_to_node будет table моего первого примера. – Antoine Leclair 13 June 2014 в 12:12
  • 3
    Отлично, это работает для меня! Тем не менее, я все еще не вижу индексов, определенных в объявлении синтаксиса __table_args__. Есть идеи? – Pehat 5 July 2016 в 14:13
  • 4
    Это также можно сделать без двигателя print(CreateTable(Model.__table__).compile(dialect=postgresql.dialect())) – jackotonye 20 April 2017 в 00:06
  • 5
    Приятно, спасибо! Я обновил ответ. – Antoine Leclair 22 April 2017 в 18:27

SQLAlchemy разработан таким образом, что не позволяет эхогенерировать созданные DDL-операторы без их фактического выполнения. AFAIK, SQLAlchemy Migrate использует mock engine для фиксации операторов без выполнения, когда используется опция --preview_sql, поэтому использование этого является одним из способов решения вашей проблемы.

-2
ответ дан Denis Otkidach 20 August 2018 в 13:00
поделиться
  • 1
    SQLAlchemy Migrate на самом деле была тем, что я искал, хотя для этого нужно немного взломать, так как я работаю над проектом с динамическими таблицами и схемами, но опять же было бы скучно, если бы не было никаких проблем ;) – Mads Madsen 26 January 2010 в 20:25

Что-то вроде этого? (из часто задаваемых вопросов SQLA)

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

8
ответ дан k107 20 August 2018 в 13:00
поделиться

Вы можете настроить ваш двигатель, чтобы сбросить последовательность создания метаданных, используя следующее:

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 оставляет это.

Другим преимуществом является то, что порядок определений схемы правилен и (почти) применим как скрипт.

4
ответ дан Lars 20 August 2018 в 13:00
поделиться

Возможно, вы имеете в виду параметр echo для sqlalchemy.create_engine?

/ 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
1
ответ дан xni 20 August 2018 в 13:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: