On Feb 16, 5:52 pm, Alexander Konovalenko <[email protected]> wrote:
> On Tue, Feb 17, 2009 at 04:25, Sridhar Ratnakumar
>
> <[email protected]> wrote:
>
> > A related question - is there a way to have two versions of datastore
> > so that I can run 'production' and 'staging' instances of my app? In
> > case, if I want to test new features without messing up the production
> > datastore, I can use the staging datastore.
>
> > If not, what is the appropriate way to do this?
>
> I'm not aware of any simple and general solution,

It probably does depend on your exact situation (like every other
engineering decision, which this one is).  But...

> but your options include:
>
> 1) Testing on the development server (SDK) only. Check out the
> --datastore_path command line option. I think you should be able to
> create a copy of a dev datastore by copying the --datastore_path file
> (when no dev server is using it), but I haven't tried it.

This is the easiest option, and, if you aren't too worried about being
able to roll back changes, or possible data corruption...

Just remember: what's deployed on production servers doesn't
necessarily match what's on the SDK.

> 2) Using a separate app. Each app has its own datastore, inaccessible
> to other apps, so you'll have to migrate your data manually between
> this staging app and your stable app.

This is the path I've taken, and it matches pretty well with the
"industry standard" for "enterprise" web-sites (whatever that means).
You can deploy your code to a server that will match your production
environment.  If it breaks, no real harm done.  If it works, you can
change the name (presumably you've already bumped the version) in
app.yaml and redeploy pretty much instantly.

Actually, this is one of the areas where GAE has a huge advantage over
pretty much every other option.

The downside, of course, is that you have to burn two apps instead of
just one.

> 3) Emulating versioned datastore manually. You will still have a
> single shared datastore, but you can write your code so that it never
> touches other versions' data. Or it can only access some other
> version's data under very specific circumstances. Or whatever. How
> this is best done heavily depends on what kind of changes you are
> trying to introduce to the datastore.

If you're doing a bunch of big, complicated, nasty sites, and you
desperately need to keep their databases distinct for security
reasons, this is the way to go.  Personally, I suspect this is what
the "cloud" version of "enterprise" software looks like.

The down-side, of course, is that it's horribly complicated.

As one possible compromise between 2) and 3), I'm going to suggest a
[n] [honestly] horrendous hack which works for me.

I don't know how well this will work for any other web framework.  I
worked this one out using web2py (about which I have extremely mixed
feelings).

You have one single GAE app.  It dispatches to multiple "applications"
based on the URL.  The first directory in the URL defines the "web
site" it dispatches to.  The second determines which controller/view
it will be using.  The third decides which method/particular instance
of the controller/view it uses.  The rest specify positional
parameters to pass to the controller.

So:
http://myapp.appspot.com/init/default/welcome
would dispatch to the init site's default controller and call its
welcome method.

http://myapp.appspot.com/staging/default/welcome
would dispatch the same thing to the staging site.

Both sites share the same datastore, which makes this approach
dangerous.  Like I said, this is really a total trade-off/hack sort of
thing.  You can add hackery to your model names so one site fudges
Model type-names, but that edges you into complication issues about
keeping things straight.

The plus side of this approach is that, when you're ready to really
deploy, you can delete your existing init site, rename staging to
init, and upload your changes.  If you need to make emergency fixes
that you're absolutely confident about, just update init.  When you're
ready to start toying with a new major (for some value of "major"
release), make a copy of init named staging, merge in your changes
(you *are* using source control, right?), rinse, and repeat.

You could take this a step further and use the same Model versioning
magic suggested in 3).  Maybe that should be approach #5?

I don't know how this approach would work under django.  Every time I
try to wrap my head around that I have an allergic reaction.

I can't really endorse web2py (every time I dealt with it I just got
frustrated because I felt like it was doing too much).  But that could
just be me.  For anyone who's still on the fence, it's definitely
worth checking out.

> Changes to your datastore schema can be risky. It is always good to
> have a full backup and test the restoration procedure periodically.

That really can't be emphasized enough.  No matter what environment
you're in.

Speaking of which, I think I'll back up my source code repository...

Regards,
James

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to