Re: [sqlalchemy] SQLAlchemy 0.7 beta 1 released
Hi Mike, I grabbed SQLAlchemy from pypi when it was still there so I could do a quick test with my current projects (yay for buildout with version pinning). I'm happy to be able to report that the upgrade was seemless, and all my tests were passing with 0.7b1. Wichert. On 2/13/11 01:51 , Michael Bayer wrote: Hey list - The first beta release of SQLAlchemy 0.7 is available for download. 0.7 is the latest iteration of our yearly cycle where each new version brings lots of new features and enhancements, refines APIs and patterns while deprecating others, and removes old APIs that have been deprecated for at least one major revision series (i.e. throughout 0.6). The initial push in 0.7 focuses on a reorganization of the event system. Over the years we've accumulated various Extension classes like MapperExtension, SessionExtension, as well as core constructs like ConnectionProxy, PoolListener, and then a bunch of other more surreptitious systems like class instrumentation events, schema association events that were not fully public. In 0.7, everything resembling an event is now available through a single unified API called sqlalchemy.event. It's a single import of a single function listen() that serves as the gateway to associating user-defined callables with all events throughout the core and ORM. All the Extension classes and similar still remain for the time being, their underlying implementations now routing through event. At the same time as event was going on, I found myself using Ants Aasma's derived attributes example like crazy in my day job. This system allows the construction of Python class attributes that produce a Python result at the object level and a SQL expression at the class level, building upon the paradigm already present in a SQLAlchemy mapped class.I enhanced the example in 0.6 such that special cases where the two situations weren't completely symmetrical could be implemented using some additional directives.It became apparent that the extremely simple idea in derived attributes was really a superset of synonym, comparable_property, and to some degree composite().So in 0.7 we've mainstreamed derived attributes as sqlalchemy.ext.hybrid. The synonym, comparable_property, and composite APIs have been refactored such that their usage is mostly the same as it was previously, but their underlying implementation uses approximately the sam e concept as ext.hybrid, and their implementations have been moved out of the core ORM modules, allowing us to simplify some things internally. The documentation now encourages the usage of sqlalchemy.ext.hybrid for customized attributes that produce new expressions derived from the class and also function at the instance level, in lieu of synonym and comparable_property. The third story of 0.7 is that we did a lot more work on speed, which includes that we've come up with a viable replacement for the mutable behavior of certain types, mainly PickleType, composite(), and postgresql.ARRAY. The mutable flag on these types is now turned off by default - while the old system of detecting in place mutation was fine for small jobs, it completely cripples the application as it begins to handle higher volumes of data, as it relied upon scanning all mutable objects in the Session in order to detect changes in these attributes. The autoflush operation basically becomes O(N) instead of O(1) the minute an object with a mutable attribute is placed in the session. A new system which allows one to construct on change events specific to the kind of data structure being stored in a scalar value is added in sqlalchemy.ext.mutable. This is a brand new system that hopefully should grow as we move through 0.7 to support various Python structures out of the box, like dicts, lists and composites of those. The turning off of mutable is likely the one most major hard change in the system - if your application relies upon in-place mutation of PickleType or postgresql.ARRAY, you'd need to turn that flag on until your app can be altered to use the new system. If your application relies upon in-place mutability of composite() (I'm assuming this is a very rare scenario, composite() isn't that common in the first place), the new system has to be used for that, which requires a little bit of modification to the user-defined composite class. Heavy users of mutable should notice an immediate effect by switching off of the old system. A long list of everything to be aware of is ready for viewing at http://www.sqlalchemy.org/trac/wiki/07Migration .While there are many changes, it is my impression that the vast majority of applications coded against 0.6 will run on 0.7 without modification, Very few changes are backwards incompatible, and of those fifteen changes which are, most are things that were never documented or were essentially silent failures. The purpose of the beta is to get community
Re: [sqlalchemy] Re: The right way to clear database of content?
Thank you GHZ, it did work! Wondering about one thing though; the recipe in the documentation iterates over the tables in reverse sorted order, like so: for table in reversed(meta.sorted_tables) Do you know what this would be good for (since your code does not care about the table order)? Arve On Mon, Feb 14, 2011 at 2:51 PM, GHZ geraint.willi...@gmail.com wrote: maybe it needs to be in a transaction: con = engine.connect() trans = con.begin() for name, table in meta.tables.items(): print table.delete() con.execute(table.delete()) trans.commit() On Feb 14, 1:29 pm, Arve Knudsen arve.knud...@gmail.com wrote: Hi What's the right way to clear a database all of content, but keep the schema? I tried the method of deleting all tables athttp:// www.sqlalchemy.org/docs/05/metadata.html#reflecting-all-tables..., but content still remains. I couldn't find any documentation on Table.delete either, for that matter. Maybe I'm missing something... Thanks, Arve -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en. -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
[sqlalchemy] Re: The right way to clear database of content?
I the order is required for Foreign Key relationships. i.e. to make sure the children are deleted before the parents. So the for table in reversed(meta.sorted_tables) example is the more correct way to delete all data. On Feb 15, 1:29 pm, Arve Knudsen arve.knud...@gmail.com wrote: Thank you GHZ, it did work! Wondering about one thing though; the recipe in the documentation iterates over the tables in reverse sorted order, like so: for table in reversed(meta.sorted_tables) Do you know what this would be good for (since your code does not care about the table order)? Arve On Mon, Feb 14, 2011 at 2:51 PM, GHZ geraint.willi...@gmail.com wrote: maybe it needs to be in a transaction: con = engine.connect() trans = con.begin() for name, table in meta.tables.items(): print table.delete() con.execute(table.delete()) trans.commit() On Feb 14, 1:29 pm, Arve Knudsen arve.knud...@gmail.com wrote: Hi What's the right way to clear a database all of content, but keep the schema? I tried the method of deleting all tables athttp:// www.sqlalchemy.org/docs/05/metadata.html#reflecting-all-tables..., but content still remains. I couldn't find any documentation on Table.delete either, for that matter. Maybe I'm missing something... Thanks, Arve -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en. -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
Re: [sqlalchemy] Re: The right way to clear database of content?
Aha, thanks again! :) Arve On Tue, Feb 15, 2011 at 1:55 PM, GHZ geraint.willi...@gmail.com wrote: I the order is required for Foreign Key relationships. i.e. to make sure the children are deleted before the parents. So the for table in reversed(meta.sorted_tables) example is the more correct way to delete all data. On Feb 15, 1:29 pm, Arve Knudsen arve.knud...@gmail.com wrote: Thank you GHZ, it did work! Wondering about one thing though; the recipe in the documentation iterates over the tables in reverse sorted order, like so: for table in reversed(meta.sorted_tables) Do you know what this would be good for (since your code does not care about the table order)? Arve On Mon, Feb 14, 2011 at 2:51 PM, GHZ geraint.willi...@gmail.com wrote: maybe it needs to be in a transaction: con = engine.connect() trans = con.begin() for name, table in meta.tables.items(): print table.delete() con.execute(table.delete()) trans.commit() On Feb 14, 1:29 pm, Arve Knudsen arve.knud...@gmail.com wrote: Hi What's the right way to clear a database all of content, but keep the schema? I tried the method of deleting all tables athttp:// www.sqlalchemy.org/docs/05/metadata.html#reflecting-all-tables..., but content still remains. I couldn't find any documentation on Table.delete either, for that matter. Maybe I'm missing something... Thanks, Arve -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en. -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en. -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
Re: [sqlalchemy] Pypi release policy
On Monday, February 14, 2011, Michael Bayer mike...@zzzcomputing.com wrote: On Feb 14, 2011, at 12:11 PM, Tarek Ziadé wrote: On Mon, Feb 14, 2011 at 6:00 PM, Michael Bayer mike...@zzzcomputing.com wrote: On Feb 14, 2011, at 5:53 AM, Tarek Ziadé wrote: On Mon, Feb 14, 2011 at 11:44 AM, Wichert Akkerman wich...@wiggy.net wrote: .. you don't release at pypi a version that breaks the latest stable. or if you do, you check the hidden attribute on that release, to avoid this problem with installers SQLAlchemy 0.7b1 is hidden. The hidden flag only hides it from humans though, not from setuptools. oh true...I forgot it's not hidden in the simple index :/ OK so you're the expert - how does one release a beta on pypi without crashing everyone's stable install ? should i just stick to sourceforge until final release ? Unfortunately, Setuptools will pick the latest version and won't care about beta tags (zc.buildout has such feature -- prefer-final, and Distutils2 too) So I guess the best way with the current eco-system is to avoid pushing any unstable release to PyPI or... if you have the time to do so, push a new 0.7 beta that makes sure people that run on the latest 0.6 can run it -- with deprecation warnings all over the place :) I'll pull it off of Pypi. We definitely do push for as much backwards compat as possible, but the release does remove / hard change things that were raising warnings throughout 0.6, as well as lots of apps rely upon undocumented behaviors which may have changed, so its inevitable that some apps will need adjustment. But the code itself should not be considered as bug-free as a stable release so in any case its not appropriate to push it into installations without explicit consent. But aren't apps supposed to use =0.6.99 to avoid backward compats issues? Apps that don't will also break when 0.7 final is on pypi. -- Eric Lemoine Camptocamp France SAS Savoie Technolac, BP 352 73377 Le Bourget du Lac, Cedex Tel : 00 33 4 79 44 44 96 Mail : eric.lemo...@camptocamp.com http://www.camptocamp.com -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
Re: [sqlalchemy] Pypi release policy
On Tue, Feb 15, 2011 at 3:27 PM, Eric Lemoine eric.lemo...@camptocamp.com wrote .. But aren't apps supposed to use =0.6.99 to avoid backward compats issues? Apps that don't will also break when 0.7 final is on pypi. There are different things here: 1/ PyPI allows projects to publish any release, and easy_install will pick the latest one, whether it's a final (==stable) or not. You can publish your trunk if you want. 2/ An application that defines a dependency can define it in different flavors: a - Give me the latest release that was made available at PyPI b - Give me the latest release from the 0.6.x series, it can use a 0.7 or 0.6.99 c - Give me version XX --- best practice once in production For applications that are using 2.a, the interpretation of most people is that the latest release at PyPI they are depending on is not a development release. If they want a development release, they do it explicitly in their environment to leave on the edge. 3/ a user types easy_install SQLAlchemy and wants the latest stable So, yeah, when 0.7.1 final will be out, some apps will break -- but they've been warned and they can choose to change their code or pin their dependency to the 0.6.x series. But right now, it's a development release that has been published for feedback as opposed to a final release. The less disruptive process (until distutils2 is available) in that case is to let people opt in to be beta testers, and let SQLAlchemy means latest stable, whether it's called by easy_install SQLAlchemy or in the install_requires option in setuptools. Cheers Tarek -- Tarek Ziadé | http://ziade.org -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
Re: [sqlalchemy] Hybrid Property and func.sum()
Hey Thanks for the answers. I have a few follow-ups if you don't mind. Hi I'm confronted with the following situation: I have two entities: Account 1:n AccountEntry AccountEntry has a column (and property) 'amount'. Now I'd like to implement a @hybrid_property.expression 'balance' on Account which uses func.sum(AccountEntry.amount) to calculate the account's balance. When I do: @balance.expression def balance(cls): return func.sum(AccountEntry.amount) sqlalchemy.exc.ProgrammingError: (ProgrammingError) (b'ERROR', b'42803', b'aggregates not allowed in WHERE clause') which is ok, since you have to have a sub-select like select * from accounts as a where (select sum(ae.amount) as balance from account_entries as ae where ae.account_id = a.id) 0 Now my question: How to achieve this using @hybrid_property.expression? Which query fragment I have to return? you can return the subquery: @balance.expression def balance(cls): return Session().query(func.sum(AccountEntry.amount)).filter(AccountEntry.account_id== cls.id).as_scalar() I finally managed the case doing this. @hybrid_property def balance(self): return db.session.query(AccountEntry.account_id, func.sum(AccountEntry.amount).label('b')).group_by(AccountEntry.account_id).having(AccountEntry.account_id== self.id).one().b @balance.expression def balance(cls): return Session().query(func.sum(AccountEntry.amount)).group_by(AccountEntry.account_id).having(AccountEntry.account_id== cls.id).as_scalar() note I'm using a do-nothing Session() there since we're generating a SQL construct that will be embedded into another. Usually when I work with aggregates like that I like to keep things more explicit. Suppose your original Account.balance descriptor: balances = session.query(AccountEntry.account_id, Account.balance.label('balance')).group_by(AccountEntry.account_id).subquery() accounts = session.query(Account).join(balances, Account.entries).filter(balances.c.balance 0) i.e. the hybrid represents a particular type of expression, but it is context-dependent. Its a typical practicality beats purity type of decision (like the rest of SQLA...) Well we're just trying out what SQLA is capable of at the moment and trying to build up a proper api. We run into a similar issue then: We have an entity Party which has n Language through PartyLanguage. On PartyLanguage there is a field called order. The one with the lowest order is the parties primary language. Now it would be very pretty to be able to do those things: 1. someparty.primary_language = Language('en') 2. assert someparty.primary_language == Language('en') 3. someparty.languages.append(Language('de')) 4. session.query(Party).filter(Party.primary_language=Language('en')).all() don't you think so? But we enquire a whole lot of problems. We managed to do most things except for 4. We implemented @primary_language.expression like this: @primary_language.expression def _primary_language_expression(cls): return Session().query(Language.iso)\ .join(PartyLanguage)\ .order_by(PartyLanguage.order)\ .group_by(PartyLanguage.party_id, Language.iso, PartyLanguage.order)\ .having(PartyLanguage.party_id==cls.id)\ .limit(1)\ .as_scalar() This works so far but there is still the need to use it in a query like this: language = Language('en') session.query(Party).filter(Party.primary_language=language.iso).all() I guess it's all about the compare behavior of the expression returned by _primary_language_expression. It includes Language as a type into the query, which leads to a not supported type error. So are we doing it all wrong, is SQLA not ment to write those kind of API's? Is it possible to achieve what we like to do? Best regards, Florian -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
[sqlalchemy] Troubles with LEFT OUTER JOIN
Can someone help me understand why I can't seem to do a simple left outer join between these two tables: q = self.session.query(Car, Invoice.id_) q = q.outerjoin(Car, Invoice) sqlalchemy.exc.ArgumentError: Can't find any foreign key relationships between 'cars' and 'cars'. Thanks, Michael --- class Car(Base): __tablename__ = 'cars' id_ = Column(Integer, primary_key=True) class Invoice(Base): __tablename__ = 'invoices' id_ = Column(Integer, primary_key=True) car_id = Column(Integer, ForeignKey('cars.id_')) car = relationship(Car, backref=backref('invoices', order_by=id_), primaryjoin=Invoice.car_id==Car.id_) -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
Re: [sqlalchemy] Hybrid Property and func.sum()
On Feb 15, 2011, at 12:02 PM, Florian Mueller wrote: Hey Thanks for the answers. I have a few follow-ups if you don't mind. Hi I'm confronted with the following situation: I have two entities: Account 1:n AccountEntry AccountEntry has a column (and property) 'amount'. Now I'd like to implement a @hybrid_property.expression 'balance' on Account which uses func.sum(AccountEntry.amount) to calculate the account's balance. When I do: @balance.expression def balance(cls): return func.sum(AccountEntry.amount) sqlalchemy.exc.ProgrammingError: (ProgrammingError) (b'ERROR', b'42803', b'aggregates not allowed in WHERE clause') which is ok, since you have to have a sub-select like select * from accounts as a where (select sum(ae.amount) as balance from account_entries as ae where ae.account_id = a.id) 0 Now my question: How to achieve this using @hybrid_property.expression? Which query fragment I have to return? you can return the subquery: @balance.expression def balance(cls): return Session().query(func.sum(AccountEntry.amount)).filter(AccountEntry.account_id==cls.id).as_scalar() I finally managed the case doing this. @hybrid_property def balance(self): return db.session.query(AccountEntry.account_id, func.sum(AccountEntry.amount).label('b')).group_by(AccountEntry.account_id).having(AccountEntry.account_id==self.id).one().b for 'self' why not use python and the collection: sum(a.amount for a in self.entries) ? @balance.expression def balance(cls): return Session().query(func.sum(AccountEntry.amount)).group_by(AccountEntry.account_id).having(AccountEntry.account_id==cls.id).as_scalar() note I'm using a do-nothing Session() there since we're generating a SQL construct that will be embedded into another. Usually when I work with aggregates like that I like to keep things more explicit. Suppose your original Account.balance descriptor: balances = session.query(AccountEntry.account_id, Account.balance.label('balance')).group_by(AccountEntry.account_id).subquery() accounts = session.query(Account).join(balances, Account.entries).filter(balances.c.balance 0) i.e. the hybrid represents a particular type of expression, but it is context-dependent. Its a typical practicality beats purity type of decision (like the rest of SQLA...) Well we're just trying out what SQLA is capable of at the moment and trying to build up a proper api. We run into a similar issue then: We have an entity Party which has n Language through PartyLanguage. On PartyLanguage there is a field called order. The one with the lowest order is the parties primary language. Now it would be very pretty to be able to do those things: 1. someparty.primary_language = Language('en') 2. assert someparty.primary_language == Language('en') 3. someparty.languages.append(Language('de')) 4. session.query(Party).filter(Party.primary_language=Language('en')).all() don't you think so? But we enquire a whole lot of problems. We managed to do most things except for 4. We implemented @primary_language.expression like this: @primary_language.expression def _primary_language_expression(cls): return Session().query(Language.iso)\ .join(PartyLanguage)\ .order_by(PartyLanguage.order)\ .group_by(PartyLanguage.party_id, Language.iso, PartyLanguage.order)\ .having(PartyLanguage.party_id==cls.id)\ .limit(1)\ .as_scalar() It doesn't always perform as well but the more relational way to do these is to use a subquery that selects the min() order: select party_id, min(order) from party_language group by party_id - select * from party_language as pl join language as lon pl.language_id=l.id join ( select party_id, min(order) as order_id from party_language group by party_id ) as min_order on min_order.order_id=pl.order_id and pl.party_id=min_order.party_id This works so far but there is still the need to use it in a query like this: language = Language('en') session.query(Party).filter(Party.primary_language=language.iso).all() language.iso is a string ? object ? You'd just need to have something there which is comparable to Language.iso. A key approach here is to work out the queries first as SQL if needed, then as ORM queries, and only at the end figure out what you'd want a @hybrid to do. @hybrid is just a syntactical trick. -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at
[sqlalchemy] Is outerjoin() not generative?
This works: Seller = aliased(Dealer) Buyer = aliased(Dealer) q = self.session.query(Car, Seller.name, Buyer.name) q = q.outerjoin((Car.seller, Seller), (Car.buyer, Buyer)) This doesn't: Seller = aliased(Dealer) Buyer = aliased(Dealer) q = self.session.query(Car, Seller.name, Buyer.name) q = q.outerjoin(Car.seller, Seller) q = q.outerjoin(Car.buyer, Buyer) sqlalchemy.exc.ArgumentError: Can't determine join between 'Join object on cars(71352432) and dealers(71704656)' and '%(78454064 dealers)s'; tables have more than one foreign key constraint relationship between them. Please specify the 'onclause' of this join explicitly. Is this by design? Thanks, Michael -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
Re: [sqlalchemy] Is outerjoin() not generative?
On Feb 15, 2011, at 5:21 PM, Michael Hipp wrote: This works: Seller = aliased(Dealer) Buyer = aliased(Dealer) q = self.session.query(Car, Seller.name, Buyer.name) q = q.outerjoin((Car.seller, Seller), (Car.buyer, Buyer)) This doesn't: Seller = aliased(Dealer) Buyer = aliased(Dealer) q = self.session.query(Car, Seller.name, Buyer.name) q = q.outerjoin(Car.seller, Seller) q = q.outerjoin(Car.buyer, Buyer) sqlalchemy.exc.ArgumentError: Can't determine join between 'Join object on cars(71352432) and dealers(71704656)' and '%(78454064 dealers)s'; tables have more than one foreign key constraint relationship between them. Please specify the 'onclause' of this join explicitly. Is this by design? the target goes first for target, onclause, syntax, note this is an 0.7 syntax: q = q.outerjoin(Seller, Car.seller) q = q.outerjoin(Buyer, Car.buyer) in 0.6 you need the tuples for target, onclause: q = q.outerjoin((Seller, Car.seller)) q = q.outerjoin((Buyer, Car.buyer)) Consult http://www.sqlalchemy.org/docs/orm/tutorial.html#querying-with-joins and http://www.sqlalchemy.org/docs/orm/query.html#sqlalchemy.orm.query.Query.join for reference on this. in this case you are using a property as the on which includes the left and right points, so you don't really need the target, the single-arg form works: q = q.outerjoin(Car.seller) q = q.outerjoin(Car.buyer) the onclause, target form is a legacy syntax which is why it still attempts to work. Thanks, Michael -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en. -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
Re: [sqlalchemy] Pypi release policy
On Tuesday, February 15, 2011, Tarek Ziadé ziade.ta...@gmail.com wrote: On Tue, Feb 15, 2011 at 3:27 PM, Eric Lemoine eric.lemo...@camptocamp.com wrote .. But aren't apps supposed to use =0.6.99 to avoid backward compats issues? Apps that don't will also break when 0.7 final is on pypi. There are different things here: 1/ PyPI allows projects to publish any release, and easy_install will pick the latest one, whether it's a final (==stable) or not. You can publish your trunk if you want. 2/ An application that defines a dependency can define it in different flavors: a - Give me the latest release that was made available at PyPI b - Give me the latest release from the 0.6.x series, it can use a 0.7 or 0.6.99 c - Give me version XX --- best practice once in production For applications that are using 2.a, the interpretation of most people is that the latest release at PyPI they are depending on is not a development release. If they want a development release, they do it explicitly in their environment to leave on the edge. 3/ a user types easy_install SQLAlchemy and wants the latest stable So, yeah, when 0.7.1 final will be out, some apps will break -- but they've been warned and they can choose to change their code or pin their dependency to the 0.6.x series. But right now, it's a development release that has been published for feedback as opposed to a final release. The less disruptive process (until distutils2 is available) in that case is to let people opt in to be beta testers, and let SQLAlchemy means latest stable, whether it's called by easy_install SQLAlchemy or in the install_requires option in setuptools. Thanks for the detailed response Tarek. It means that beta testers won't be able to download SQLAlchemy betas from PyPI, and will have to install betas from source? Cheers, -- Eric Lemoine Camptocamp France SAS Savoie Technolac, BP 352 73377 Le Bourget du Lac, Cedex Tel : 00 33 4 79 44 44 96 Mail : eric.lemo...@camptocamp.com http://www.camptocamp.com -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.