Giter VIP home page Giter VIP logo

alembic's Introduction

SQLAlchemy

PyPI PyPI - Python Version PyPI - Downloads

The Python SQL Toolkit and Object Relational Mapper

Introduction

SQLAlchemy is the Python SQL toolkit and Object Relational Mapper that gives application developers the full power and flexibility of SQL. SQLAlchemy provides a full suite of well known enterprise-level persistence patterns, designed for efficient and high-performing database access, adapted into a simple and Pythonic domain language.

Major SQLAlchemy features include:

  • An industrial strength ORM, built from the core on the identity map, unit of work, and data mapper patterns. These patterns allow transparent persistence of objects using a declarative configuration system. Domain models can be constructed and manipulated naturally, and changes are synchronized with the current transaction automatically.
  • A relationally-oriented query system, exposing the full range of SQL's capabilities explicitly, including joins, subqueries, correlation, and most everything else, in terms of the object model. Writing queries with the ORM uses the same techniques of relational composition you use when writing SQL. While you can drop into literal SQL at any time, it's virtually never needed.
  • A comprehensive and flexible system of eager loading for related collections and objects. Collections are cached within a session, and can be loaded on individual access, all at once using joins, or by query per collection across the full result set.
  • A Core SQL construction system and DBAPI interaction layer. The SQLAlchemy Core is separate from the ORM and is a full database abstraction layer in its own right, and includes an extensible Python-based SQL expression language, schema metadata, connection pooling, type coercion, and custom types.
  • All primary and foreign key constraints are assumed to be composite and natural. Surrogate integer primary keys are of course still the norm, but SQLAlchemy never assumes or hardcodes to this model.
  • Database introspection and generation. Database schemas can be "reflected" in one step into Python structures representing database metadata; those same structures can then generate CREATE statements right back out - all within the Core, independent of the ORM.

SQLAlchemy's philosophy:

  • SQL databases behave less and less like object collections the more size and performance start to matter; object collections behave less and less like tables and rows the more abstraction starts to matter. SQLAlchemy aims to accommodate both of these principles.
  • An ORM doesn't need to hide the "R". A relational database provides rich, set-based functionality that should be fully exposed. SQLAlchemy's ORM provides an open-ended set of patterns that allow a developer to construct a custom mediation layer between a domain model and a relational schema, turning the so-called "object relational impedance" issue into a distant memory.
  • The developer, in all cases, makes all decisions regarding the design, structure, and naming conventions of both the object model as well as the relational schema. SQLAlchemy only provides the means to automate the execution of these decisions.
  • With SQLAlchemy, there's no such thing as "the ORM generated a bad query" - you retain full control over the structure of queries, including how joins are organized, how subqueries and correlation is used, what columns are requested. Everything SQLAlchemy does is ultimately the result of a developer-initiated decision.
  • Don't use an ORM if the problem doesn't need one. SQLAlchemy consists of a Core and separate ORM component. The Core offers a full SQL expression language that allows Pythonic construction of SQL constructs that render directly to SQL strings for a target database, returning result sets that are essentially enhanced DBAPI cursors.
  • Transactions should be the norm. With SQLAlchemy's ORM, nothing goes to permanent storage until commit() is called. SQLAlchemy encourages applications to create a consistent means of delineating the start and end of a series of operations.
  • Never render a literal value in a SQL statement. Bound parameters are used to the greatest degree possible, allowing query optimizers to cache query plans effectively and making SQL injection attacks a non-issue.

Documentation

Latest documentation is at:

https://www.sqlalchemy.org/docs/

Installation / Requirements

Full documentation for installation is at Installation.

Getting Help / Development / Bug reporting

Please refer to the SQLAlchemy Community Guide.

Code of Conduct

Above all, SQLAlchemy places great emphasis on polite, thoughtful, and constructive communication between users and developers. Please see our current Code of Conduct at Code of Conduct.

License

SQLAlchemy is distributed under the MIT license.

alembic's People

Contributors

akamyshnikova avatar aodag avatar bbinet avatar brycelohr avatar caselit avatar charlax avatar dahlia avatar dltacube avatar dreamsorcerer avatar dtheodor avatar exhuma avatar explodingcabbage avatar gordthompson avatar ijl avatar iurisilvio avatar jameslamb avatar jayaddison avatar kasium avatar maartenkos avatar marcinkuzminski avatar maresb avatar mikeywaites avatar msabramo avatar nibrahim avatar saifelse avatar simonbowly avatar tilmank avatar utek avatar ziima avatar zzzeek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alembic's Issues

Column renames not supported on SQLite

Migrated issue, originally created by Wichert Akkerman (@wichert)

SQLite does not support renaming a column directly, so you need a magic dance: create a new column, copy the right data to it and then remove the old column, taking care to only add constraints after copying the data.

Make version table name configurable

Migrated issue, originally created by Karol Kuczmarski (@Xion)

It's currently alembic_version, but it would be nice if this was configurable - either in alembic.ini, or (more likely) in env.py.

pylons template env file has some typos

Migrated issue, originally created by Marcin Kuzminski (@marcinkuzminski)

Hi, I'm using dev version of alembic and I'm trying to integrate it to my project. noticed there is small typo in the env.py file:

#!python

    # if pylons app already in, don't create a new app
    from pylons import config as pylons_config
    pylons_config['__file__']
except:
    # can use config['__file__'] here, i.e. the Pylons
    # ini file, instead of alembic.ini
    config_file = config.get_main_option('pylons_config_file')
    config_file = config.config_file_name

config. module/variable is undefined in that template

compare types on dialect impl

Migrated issue, originally created by Michael Bayer (@zzzeek)

more tests. if using TypeDecorator with selectable type, a match will fail if the affinity test isn't done in a dialect-specific way.

migrations are including dialect-specific datatypes for columns it should already know the datatype for

Migrated issue, originally created by dieselmachine (@dieselmachine)

I have a simple test project i built, and generated the initial commit, and upgraded to it. The relevant section from the migration file is this:

#!python

op.create_table('user_profiles',
    ...
    sa.Column('po_zip', sa.String(length=12), nullable=True),
    ...

I then edited the po_zip column on the model to be String(14) instead, and generated a new revision using autogenerate, and the detected change looks like this:

#!python

    op.alter_column('user_profiles', u'po_zip', 
               existing_type=mysql.VARCHAR(length=12), 
               type_=sa.String(length=14), 
               existing_nullable=True)

Now, the inclusion of mysql.* implies the migration read from the db to determine the diffs, rather than running the present migrations from base to head and using that as the base for comparison.

I'd like the generated diffs to be comparisons between the current orm.metadata and the generated metadata by running previous revisions up to the current head, rather than reading from the database. I'd like the generated diff to look like this:

#!python

    op.alter_column('user_profiles', u'po_zip', 
               existing_type=sa.String(length=12), 
               type_=sa.String(length=14), 
               existing_nullable=True)

Is there a way to accomplish this? Is autogenerate just comparing the current orm to the raw db everytime?

autogenerate for first revision of existing database

Migrated issue, originally created by Anonymous

I tried create simple test project, create user and database, create table via

User.__table__.create(bind=db.engine)

and run autogenerate, alembic (or sqlalchemy?) don't recognize TYPE fields.

alembic revision --autogenerate -m "test autogenerate"

INFO  [alembic.migration] Context impl PostgresqlImpl.
INFO  [alembic.migration] Will assume transactional DDL.
/Volumes/storage/code/venv/lib/python2.7/site-packages/sqlalchemy/engine/reflection.py:47: SAWarning: Did not recognize type '"TYPE_SEX"' of column 'sex'
  ret = fn(self, con, *args, **kw)
INFO  [alembic.autogenerate] Couldn't determine database type for column 'user.sex'
  Generating /Volumes/storage/code/alemb/alembproject/versions/eca99148094_test_au
  togenerate.py...done

Attached project code.

Thanks.


Attachments: alemb.zip

autogenerate event model

Migrated issue, originally created by Michael Bayer (@zzzeek)

was previously: run autogen diffs through the context, give them a chance to update, include MSSQL flags for default/check

The key event we need is some way to intercept the diff stream. I'm not sure yet if we should consider a full blown event system, which if we were to do that I'd use SQLAlchemy's event dispatch system as the basis, though if we were to do that I'd like to identify many points throughout Alembic where this would be appropriate.

Or smaller scale, just a function that we pass to the environment that receives the diff stream may be all that's needed.

In particular we need to support the use case of systems that use customized metadata schemes, such as Column subclasses, automated column/constraint additions, and others, so that the generated schema objects match the conventions in use by the application. Ideally we should add much more of a document building on the start of things at http://www.sqlalchemy.org/trac/wiki/UsageRecipes/NamingConventions for how to build Column subclasses, table events, all of that, and then also have it integrate with Alembic events too.

autogenerate, could generate invalid python code

Migrated issue, originally created by Marcin Kuzminski (@marcinkuzminski)

I'm testing out autogenerate and got something like that in the proposed script:

def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('users_group_repo_group_to_perm')
    op.drop_table('notifications')
    op.drop_table('user_to_notification')
    op.drop_table('user_repo_group_to_perm')
    op.drop_table('changeset_comments')
    op.create_table(u'group_to_perm',
    sa.Column(u'group_to_perm_id', sa.INTEGER(), server_default='nextval('group_to_perm_group_to_perm_id_seq'::regclass)', nullable=False), #<-- PROBLEM !
    sa.Column(u'user_id', sa.INTEGER(), nullable=False),
    sa.Column(u'permission_id', sa.INTEGER(), nullable=False),
    sa.Column(u'group_id', sa.INTEGER(), nullable=False),
    sa.ForeignKeyConstraint(['group_id'], [u'groups.group_id'], name=u'group_to_perm_group_id_fkey'),
    sa.ForeignKeyConstraint(['permission_id'], [u'permissions.permission_id'], name=u'group_to_perm_permission_id_fkey'),
    sa.ForeignKeyConstraint(['user_id'], [u'users.user_id'], name=u'group_to_perm_user_id_fkey'),
    sa.PrimaryKeyConstraint(u'group_to_perm_id', name=u'group_to_perm_pkey')
    )
    op.alter_column(u'user_logs', u'repository_id', 
               existing_type=sa.INTEGER(), 
               nullable=False)

i think it can be patched with

diff --git a/alembic/autogenerate.py b/alembic/autogenerate.py
--- a/alembic/autogenerate.py
+++ b/alembic/autogenerate.py
@@ -401,17 +401,17 @@ def _render_server_default(default, auto
             default = default.arg
         else:
             default = str(default.arg.compile(dialect=autogen_context['dialect']))
     if isinstance(default, basestring):
         # TODO: this is just a hack to get 
         # tests to pass until we figure out
         # WTF sqlite is doing
         default = re.sub(r"^'|'$", "", default)
-        return "'%s'" % default
+        return "'''%s'''" % default
     else:
         return None
 
 def _repr_type(prefix, type_, autogen_context):
     mod = type(type_).__module__
     imports = autogen_context.get('imports', None)
     if mod.startswith("sqlalchemy.dialects"):
         dname = re.match(r"sqlalchemy\.dialects\.(\w+)", mod).group(1)

Missing 'autogen_context' param in alembic.autogenerate._render_check_constraint.

Migrated issue, originally created by Stefano (@stefanofontanelli)

I got the error below when I try to run:

alembic revision --autogenerate -m "test"



INFO  [alembic.migration] Context impl MySQLImpl.
INFO  [alembic.migration] Will assume non-transactional DDL.
INFO  [alembic.autogenerate] Detected added table 'files'
INFO  [alembic.autogenerate] Detected added table 'node_infos_links__node_infos'
INFO  [alembic.autogenerate] Detected added table 'node_infos_images__files'
INFO  [alembic.autogenerate] Detected added table 'users'
INFO  [alembic.autogenerate] Detected added table 'node_infos_keywords'
INFO  [alembic.autogenerate] Detected added table 'settings'
INFO  [alembic.autogenerate] Detected added table 'node_infos'
INFO  [alembic.autogenerate] Detected added table 'node_infos_files__files'
INFO  [alembic.autogenerate] Detected added table 'users_groups'
INFO  [alembic.autogenerate] Detected added table 'languages'
INFO  [alembic.autogenerate] Detected added table 'themes'
INFO  [alembic.autogenerate] Detected added table 'groups'
INFO  [alembic.autogenerate] Detected added table 'nodes_banners__files'
INFO  [alembic.autogenerate] Detected added table 'keywords'
INFO  [alembic.autogenerate] Detected added table 'nodes'
INFO  [alembic.autogenerate] Detected added table 'views'
INFO  [alembic.autogenerate] Detected added table 'views_descriptions'
INFO  [alembic.autogenerate] Detected added table 'setting_types'
Traceback (most recent call last):
  File "/home/stefano/projects/aybu-1.0/bin/alembic", line 9, in <module>
    load_entry_point('alembic==0.2.0', 'console_scripts', 'alembic')()
  File "/home/stefano/projects/aybu-1.0/local/lib/python2.7/site-packages/alembic/config.py", line 228, in main
    **dict((k, getattr(options, k)) for k in kwarg)
  File "/home/stefano/projects/aybu-1.0/local/lib/python2.7/site-packages/alembic/command.py", line 81, in revision
    script.run_env()
  File "/home/stefano/projects/aybu-1.0/local/lib/python2.7/site-packages/alembic/script.py", line 123, in run_env
    util.load_python_file(self.dir, 'env.py')
  File "/home/stefano/projects/aybu-1.0/local/lib/python2.7/site-packages/alembic/util.py", line 149, in load_python_file
    module = imp.load_source(module_id, path, open(path, 'rb'))
  File "alembic/env.py", line 76, in <module>
    run_migrations_online()
  File "alembic/env.py", line 69, in run_migrations_online
    context.run_migrations()
  File "<string>", line 3, in run_migrations
  File "/home/stefano/projects/aybu-1.0/local/lib/python2.7/site-packages/alembic/environment.py", line 384, in run_migrations
    self.get_context().run_migrations(**kw)
  File "/home/stefano/projects/aybu-1.0/local/lib/python2.7/site-packages/alembic/migration.py", line 153, in run_migrations
    self):
  File "/home/stefano/projects/aybu-1.0/local/lib/python2.7/site-packages/alembic/command.py", line 73, in retrieve_migrations
    autogen.produce_migration_diffs(context, template_args, imports)
  File "/home/stefano/projects/aybu-1.0/local/lib/python2.7/site-packages/alembic/autogenerate.py", line 37, in produce_migration_diffs
    _indent(_produce_upgrade_commands(diffs, autogen_context))
  File "/home/stefano/projects/aybu-1.0/local/lib/python2.7/site-packages/alembic/autogenerate.py", line 231, in _produce_upgrade_commands
    buf.append(_invoke_command("upgrade", diff, autogen_context))
  File "/home/stefano/projects/aybu-1.0/local/lib/python2.7/site-packages/alembic/autogenerate.py", line 246, in _invoke_command
    return _invoke_adddrop_command(updown, args, autogen_context)
  File "/home/stefano/projects/aybu-1.0/local/lib/python2.7/site-packages/alembic/autogenerate.py", line 268, in _invoke_adddrop_command
    return cmd_callables[1](*cmd_args)
  File "/home/stefano/projects/aybu-1.0/local/lib/python2.7/site-packages/alembic/autogenerate.py", line 313, in _add_table
    table.constraints]
  File "/home/stefano/projects/aybu-1.0/local/lib/python2.7/site-packages/alembic/autogenerate.py", line 427, in _render_constraint
    return renderer(constraint, autogen_context)
TypeError: _render_check_constraint() takes exactly 1 argument (2 given)

I checked the code: missing 'autogen_context' param in alembic.autogenerate._render_check_constraint.

def _render_check_constraint(constraint):
    opts = []
    if constraint.name:
        opts.append(("name", repr(constraint.name)))
    return "%(prefix)sCheckConstraint('TODO')" % {
            "prefix":_sqlalchemy_autogenerate_prefix(autogen_context)
        }

I attached a patch which adds the missing parameter in the function signature.

def _render_check_constraint(constraint, autogen_context):
    opts = []
    if constraint.name:
        opts.append(("name", repr(constraint.name)))
    return "%(prefix)sCheckConstraint('TODO')" % {
            "prefix":_sqlalchemy_autogenerate_prefix(autogen_context)
        }

Attachments: fix_render_check_constraint.patch

need more checks for alembic_version in autogen

Migrated issue, originally created by Michael Bayer (@zzzeek)

if meta.reflect() is used to get all tables, then alembic_version is in the given metadata being compared, so need to skip on this end as well as when autogen reads from the DB.

Config class require a file name

Migrated issue, originally created by miniwark NA (@miniwark)

In config.py the docstrings say than the .Config class can be construct without a file with this example :

from alembic.config import Config
alembic_cfg = Config()
alembic_cfg.set_main_option("script_location", "myapp:migrations")
alembic_cfg.set_main_option("url", "postgresql://foo/bar")

When i try to do so and then upgrade :

from alembic import command
command.upgrade(alembic_cfg, 'head')

The upgrade command break because it require a config filename.

...
  File "/lib/python2.7/site-packages/alembic/command.py", line 108, in upgrade
    script.run_env()
  File "/lib/python2.7/site-packages/alembic/script.py", line 167, in run_env
    util.load_python_file(self.dir, 'env.py')
  File "/lib/python2.7/site-packages/alembic/util.py", line 176, in load_python_file
    module = imp.load_source(module_id, path, open(path, 'rb'))
  File "/testprojects/scripts/alembic/env.py", line 12, in <module>
    fileConfig(config.config_file_name)
  File "/usr/lib64/python2.7/logging/config.py", line 68, in fileConfig
    cp.read(fname)
  File "/usr/lib64/python2.7/ConfigParser.py", line 292, in read
    for filename in filenames:
TypeError: 'NoneType' object is not iterable

Alternaly the 'url' example may lead to a KeyError as it's 'sqlalchely.url' witch is need.

I was able to workaround this with this code by telling Config to use an necessary .ini file (in a pyramid project) :

from alembic.config import Config
from alembic import command
from pyramid.paster import get_appsettings

settings = get_appsettings(developement.ini)
alembic_cfg = Config('developement.ini')
alembic_cfg.set_section_option('alembic', 'script_location', 'anuket:scripts/alembic')
alembic_cfg.set_section_option('alembic', 'sqlalchemy.url', settings['sqlalchemy.url'])

command.upgrade(alembic_cfg, 'head')

add postgresql_using option to alter_column

Migrated issue, originally created by Michael Bayer (@zzzeek)

to change the type of a col between two non-convertible types, PG wants an option "USING" for this:

http://www.postgresql.org/docs/8.1/static/sql-altertable.html

that is:

ALTER TABLE images ALTER COLUMN id TYPE INTEGER using id::integer

This is not something I feel like having Alembic guess on and/or look up in a big hard-to-maintain translation table, so for now we can just have it be explicit as needed with postgresql_using.

mysql.TINYINT(display_width=1) vs sa.Boolean()

Migrated issue, originally created by dieselmachine (@dieselmachine)

I'm generating diffs that are failing to equate these two types (in autogenerate._compare_columns). I understand the two are not strictly equivalent, but I found this note in the sqlalchemy comments (dialects/mysql/base.py):

"Note: following the usual MySQL conventions, TINYINT(1) columns reflected during Table(..., autoload=True) are treated as Boolean columns."

I am not sure whether the issue lies with sqlalchemy or alembic, but I did some grepping through the sqla code attempting to find where the tinyint was being cast to boolean and I was unable to find anything that looked relevant.

I'd like alembic to not detect these as changes during autogenerate, is there something I need to do in order to have this work?

how begin using alembic with existing database and autogenerate?

Migrated issue, originally created by Anonymous

Sorry that I write here.

If I use existing database with tables and want add some tables alembic works. But if I add --autogenerate option and add new table that does not exist in database alembic trying remove all tables which he don't know and add my new one :)
How I can fix this?

Maybe in alembic add option like "scan database" or "scan metadata and database" ?
And after this it generate base revision.

Thanks!

Alembic inconvenient to use programmatically

Migrated issue, originally created by Daniel Miller (@millerdev)

I'd like to call alembic commands programmatically, but the config object is proving rather difficult to use that way. Here's my use case: I want to write tests for my migrations. I'd like to use alembic to down/upgrade the database to a particular revision and then run some tests on the db to verify that things look right. Am I overlooking something obvious, or is there no good way to make alembic do its thing without a config file on disk?

The root of the problem seems to be the tight coupling to ConfigParser, as a fundamentally file-based structure. It would be nice to support a simpler programmatic configuration object such as a plain dict.

Postgresql "offline mode" fails on Enums

Migrated issue, originally created by Anonymous

I get something to this effect when trying to debug the issue:

  File "/Users/kylejohnson/dev/nlg/lib/python2.7/site-packages/SQLAlchemy-0.7.3-py2.7-macosx-10.4-x86_64.egg/sqlalchemy/dialects/postgresql/base.py", line 441, in create
    not bind.dialect.has_type(bind, self.name, schema=self.schema):
  File "/Users/kylejohnson/dev/nlg/lib/python2.7/site-packages/SQLAlchemy-0.7.3-py2.7-macosx-10.4-x86_64.egg/sqlalchemy/dialects/postgresql/base.py", line 1039, in has_type
    return bool(cursor.scalar())
AttributeError: 'NoneType' object has no attribute 'scalar'

It would appear the postgres dialect is trying to query a real, live server to find out if the enum already exists; this of course fails since the server is mocked up with limited functionality for offline mode.

autogenerate server_defaut repr

Migrated issue, originally created by Michael Bayer (@zzzeek)

Column('updated_at', TIMESTAMP(), server_default='TIMEZONE('utc', CURRENT_TIMESTAMP)', nullable=False),

More descriptive variable names

Migrated issue, originally created by dieselmachine (@dieselmachine)

I recently forked alembic, and have been making a lot of changes to implement multi-schema support. One thing I've noticed is the variable 'tname' tends to be used frequently to refer to what sqlalchemy considers Table.fullname (schema.tablename if schema is present, else tablename). tname implies (to me, at least) table.name, which has no schema. Currently, we have the variable tname frequently referring to the table's fullname, yet being passed into functions which will break if they receive a fullname (backticks around a dotted tablename, ie schema.table, rather than schema.table)

It might be a good idea to start distinguishing the two, perhaps via a tfullname vs tname naming scheme based on which format you're referring to, that way when you see a random reference to a tablename in a file, you'll know whether or not it needs special handling to coerce to something usable.

Also, given that so many functions takes a 'schema' parameter, it might be a good idea to take special care when using 'from sqlalchemy import schema', as that then requires aliasing of the schema kwarg in places, which makes things inconsistent. Again, a minor issue, but my fork is now generating migration files where some commands have a "schema" kwarg, and some have "schema_". Given the destination endpoint for all the commands is in the impl file, and those are all set up to accept the 'schema' kwarg, it would be nice to be able to pass it through without concerning oneself with aliasing it partway through the process.

Allow specifying script_location as resource specification

Migrated issue, originally created by Sok Ann Yap (@sayap)

To deploy the migration scripts more easily, I intend to bundle the script_location directory together with my .egg package. This requires alembic to support using resource specification for script_location, otherwise I have to keep changing the value in the .ini file whenever a newer .egg is deployed.

Attached is a diff for that. And thanks for alembic, it is awesome :)


Attachments: 29.1.patch | 29.patch | alembic-script-location.diff

Hard to use ops outside of alembic scripts

Migrated issue, originally created by Wichert Akkerman (@wichert)

I already have a simple upgrade framework that I want to keep using, but the operations implemented by alembic are very useful (and look saner than sqlalchemy-migrate), so I'm interested in using just the underlying alembic ops. This appears to be hard to do: the operations require a global context, but there is no API to configure that. This seems to at get some things going:

#!python
from alembic import context
from alembic.config import Config

config = Config(None)
context._opts(config, None, fn=None)
connection = meta.Session.connection()
context.configure(connection=connection, target_metadata=meta.metadata)

but it feels like API abuse to do it this way.


Attachments: 19.patch

bulk_insert() fails in 0.3.0

Migrated issue, originally created by Bill Schindler (@bitranch)

Running a bulk_insert in 0.3.0 produces a traceback:

File "./db-schema/versions/30a9c8146585.py", line 55, in upgrade
    op.bulk_insert(reflevel, vals)
File "<string>", line 7, in bulk_insert
File "/opt/system-builds/alembic/eggs/alembic-0.3.0-py2.6.egg/alembic/operations.py", line 573, in bulk_insert
    self.impl.bulk_insert(table, rows)
File "/opt/system-builds/alembic/eggs/alembic-0.3.0-py2.6.egg/alembic/ddl/impl.py", line 169, in bulk_insert
    self._exec(table.insert(), *rows)
TypeError: _exec() takes at most 5 arguments (2785 given)

It looks like that last call should maybe be
self._exec(table.insert(), multiparams=rows)

Error with Enum and autogenerate

Migrated issue, originally created by Marc Schlaich (@schlamar)

Having a column with an Enum generates the following line on autogenerate which fails on the upgrade command

#!python
sa.CheckConstraint('TODO')

alembic init causes IOError on PyPy

Migrated issue, originally created by Hong Minhee (@dahlia)

alembic init}}} command causes {{{IOError}}} on PyPy 1.8.
{{{alembic init


#!console
$ alembic init ./migrate
  Creating directory /.../dir/migrate...done
  Creating directory /.../dir/migrate/versions...done
  Generating /.../dir/migrate/script.py.mako...done
  Generating /.../dir/migrate/__pycache__...FAILED
Traceback (most recent call last):
  ...
IOError: [Errno 21] Is a directory: '/.../site-packages/alembic-0.3.2-py2.7.egg/alembic/templates/generic/__pycache__'

The complete traceback is:

#!pytb
Traceback (most recent call last):
  File "app_main.py", line 51, in run_toplevel
  File "/.../bin/alembic", line 9, in <module>
    load_entry_point('alembic==0.3.2', 'console_scripts', 'alembic')()
  File "/.../site-packages/alembic-0.3.2-py2.7.egg/alembic/config.py", line 229, in main
    **dict((k, getattr(options, k)) for k in kwarg)
  File "/.../site-packages/alembic-0.3.2-py2.7.egg/alembic/command.py", line 56, in init
    output_file
  File "/.../site-packages/alembic-0.3.2-py2.7.egg/alembic/script.py", line 269, in _copy_file
    src, dest)
  File "/.../site-packages/alembic-0.3.2-py2.7.egg/alembic/util.py", line 149, in status
    ret = fn(*arg, **kw)
  File "/usr/lib/pypy/lib-python/2.7/shutil.py", line 116, in copy
    copyfile(src, dst)
  File "/usr/lib/pypy/lib-python/2.7/shutil.py", line 81, in copyfile
    with open(src, 'rb') as fsrc:
IOError: [Errno 21] Is a directory: '/.../site-packages/alembic-0.3.2-py2.7.egg/alembic/templates/generic/__pycache__'

53b9cccf73a7655191186fcc9b721f7a448255c0 broke compatibility with SQLAlchemy 0.6

Migrated issue, originally created by Felix Schwarz (@felixschwarz)

As of 53b9ccc alembic won't work anymore with SQLAlchemy 0.6.5:

  File "…/alembic/__init__.py", line 8, in <module>
    from alembic import op
  File "…/alembic/op.py", line 1, in <module>
    from alembic.operations import Operations
  File "…/alembic/operations.py", line 2, in <module>
    from alembic.ddl import impl
  File "…/alembic/ddl/__init__.py", line 1, in <module>
    import postgresql, mysql, sqlite, mssql
  File "…/alembic/ddl/postgresql.py", line 1, in <module>
    from alembic.ddl.impl import DefaultImpl
  File "…/alembic/ddl/impl.py", line 19, in <module>
    class DefaultImpl(object):
  File "…/alembic/ddl/impl.py", line 61, in DefaultImpl
    params=sqla_util.immutabledict()):
AttributeError: 'module' object has no attribute 'immutabledict'

API code uses sys.exit to signal errors

Migrated issue, originally created by Robert Buchholz (@rbuchholz)

The documentation describes the following as API to stamp a database:

    from alembic.config import Config
    from alembic import command
    alembic_cfg = Config(path_to_config)
    command.stamp(alembic_cfg, "head")

If stamp encounters an error reading the config file, it will use util.err which stops program execution immediately:

def err(message):
    msg(message)
    sys.exit(-1)

While it is possible to catch SystemExit, I would favor a more specific exception that includes the error message for the API part of the command.

Alembic doesn't cleaup up after itself

Migrated issue, originally created by Daniel Miller (@millerdev)

Some alembic commands (for example, upgrade and downgrade) create an engine and a connection, but these resources are not cleaned up on exit. I have some tests that create a new database, run alembic commands, and finally drop the database. However, the database cannot be dropped until the alembic resources are cleaned up. These resources are created in env.py. Should the env.py templates include some resource cleanup?

#!python

engine = engine_from_config(
    config.get_section(config.config_ini_section),
    prefix='sqlalchemy.')

connection = engine.connect()
try:
    context.configure(
                connection=connection, 
                target_metadata=target_metadata
                )

    with context.begin_transaction():
        context.run_migrations()
finally:
    connection.close()
    engine.dispose()

remove the print staments in alembic.command

Migrated issue, originally created by miniwark NA (@miniwark)

alembic.command use a few print commands to display command results. For example in current function.

If i try to use command.current in another script the version is always printed in the console.

Example script :

#!python

from alembic.config import Config
from alembic import command
    
alembic_cfg = Config('alembic.ini')
version = command.current(alembic_cfg)
if version:
   ...

This will effectively get the requested version but also print the version with may not be wanted in another script.

suggestion : return a string instead instead of using print

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.