On 11 Apr 2015, at 01:00, Mike Bayer <mike...@zzzcomputing.com> wrote:

> 
> 
> On 4/10/15 4:55 PM, Giovanni Torres wrote:
>> 
>> 
>> CREATE TABLE foobar (
>>     id INTEGER NOT NULL AUTO_INCREMENT,
>>     CONSTRAINT pk_foobar PRIMARY KEY (id)
>> )
>> 
>> need a test case illustrating the failure.
>> The main problem with this is that I can’t see a way to modify primary keys 
>> with alembic in a way that works with MySQL and Postgres.
>> 
>> MySQL lets you create a table with a proper primary key name, but then you 
>> can’t use the name. See 
>> http://dev.mysql.com/doc/refman/5.5/en/create-table.html, specifically:
>> 
>> "A PRIMARY KEY is a unique index where all key columns must be defined as 
>> NOT NULL. If they are not explicitly declared as NOT NULL, MySQL declares 
>> them so implicitly (and silently). A table can have only one PRIMARY KEY. 
>> The name of a PRIMARY KEY is always PRIMARY, which thus cannot be used as 
>> the name for any other kind of index.”
>> 
>> Therefore, if I have a table as follows, which I then try to modify the 
>> primary key:
>> 
>> t = Table('foobar', metadata,
>>         Column('id', Integer, primary_key=True),
>>         Column('foo', Integer)
>>     )
>> 
>> An Alembic script would look like this *for MySQL*:
>> 
>> def upgrade():
>>     op.drop_constraint('pk_foobar', ‘foobar’, type_=‘primary')
>>     op.create_primary_key(None, 'foobar', ['id', 'foo'])
>> 
>> However, it doesn’t work. I get: (1075, 'Incorrect table definition; there 
>> can be only one auto column and it must be defined as a key') 'ALTER TABLE 
>> foobar DROP PRIMARY KEY ' ()
>> 
>> alembic —sql upgrade 675e5c38a0b:head shows:
>> 
>> -- Running upgrade 675e5c38a0b -> c37885f5cff
>> 
>> ALTER TABLE foobar DROP PRIMARY KEY;
>> 
>> ALTER TABLE foobar ADD PRIMARY KEY (id, foo);
>> 
>> UPDATE alembic_version SET version_num='c37885f5cff' WHERE 
>> alembic_version.version_num = '675e5c38a0b’;
>> 
>> Then, I proceed to do it as follows:
>> 
>> def upgrade():
>>     op.execute('ALTER TABLE foobar DROP PRIMARY KEY, ADD PRIMARY KEY (id, 
>> foo)’)
>> 
>> Which works OK, however it doesn’t work in Postgres, it’s invalid SQL, to 
>> make it work in Postgres I would do:
> well like so many openstack scripts I see you'd need to conditional this on 
> MySQL for now:
> 
> if op.get_bind().name == "mysql":
>    op.execute(" ... ")
> else:
>    op.drop_constraint(....)
>    op.create_primary_key(...)
> 
> within Alembic we'd probably need a new op directive that does an in-place 
> alter of a PK in a backend-agnostic way.

Thank you very much Mike. I think this pretty much covers all my doubts.

> 
> 
> 
>> 
>> def upgrade():
>>     op.drop_constraint('pk_foobar', 'foobar')
>>     op.create_primary_key(None, 'foobar', ['id', 'foo'])
>> 
>> Which works very well, alembic —sql upgrade 675e5c38a0b:head shows:
>> 
>> -- Running upgrade 675e5c38a0b -> c37885f5cff
>> 
>> ALTER TABLE foobar DROP CONSTRAINT pk_foobar;
>> 
>> ALTER TABLE foobar ADD CONSTRAINT pk_foobar PRIMARY KEY (id, foo);
>> 
>> UPDATE alembic_version SET version_num='c37885f5cff' WHERE 
>> alembic_version.version_num = '675e5c38a0b';
>> 
>> COMMIT;
>> 
>> To conclude, don’t know how to make it work with MySQL and Postgres.
>> 
>>>> o I also seem to be hitting a bug in sqlalchemy similar to this one: 
>>>> https://bitbucket.org/zzzeek/sqlalchemy/issue/3067/naming-convention-exception-for-boolean.
>>>>  I get this error: InvalidRequestError: Naming convention including 
>>>> %(constraint_name)s token requires that constraint is explicitly named.
>>> Several approaches to this.
>>> 
>>> The first is that you specify constraint_name for your Boolean type, using 
>>> the "name" parameter.
>>> 
>>> Second, forego the use of a CHECK constraint with the Boolean type by using 
>>> create_constraint=False.
>>> 
>>> Third, instead of using %(constraint_name)s in your CHECK constraint, you 
>>> use %(column_0_name)s.   Barbican will have to upgrade to SQLAlchemy 1.0 
>>> for this, but the good news is that SQLA 1.0 will be released before the 
>>> Vancouver summit and you can invite me to a Barbican session there in order 
>>> to start selling this.
>> Thanks for the offer! However, this is a bit over my head at the moment. I’m 
>> just trying to get my first commit in. But, hopefully the code review 
>> generates some discussion and I could try to push it there. I also know one 
>> of the core members, which might help.
>> 
>>> Fourth, essentially emulate 1.0's behavior by removing "ck_" from the 
>>> naming convention and using a straight "after_parent_attach" event to set 
>>> up the name; this is how naming conventions were done before the feature 
>>> was added.  This is illustrated here: 
>>> https://bitbucket.org/zzzeek/sqlalchemy/wiki/UsageRecipes/NamingConventions 
>>> . This is also a potential approach to the foreign key issue as well.
>> Thanks, this seems to me the way to go. I could fix the constraint_name 
>> issue and the 64 character limit in one go.
>> 
>>> I'm zzzeek on #openstack-dev if you want to chat further!
>> Thanks for all the help!
>> 
>>>> All this is compounded by the fact that we're also trying to support 
>>>> Postgres (which works very well by way), so we can't only cater to MySQL's 
>>>> nuisances.
>>>> 
>>>> The bug I'm trying to fix is in a future OpenStack component: 
>>>> https://bugs.launchpad.net/barbican/+bug/1415869
>>>> 
>>>> Any suggestion or shared experiences about how to deal with any of these 
>>>> issues is welcome!
>>>> 
>>>> -- 
>>>> Giovanni

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to