turbogears-admin shell <initial data file>

4 views
Skip to first unread message

xtian

unread,
Oct 1, 2005, 7:47:07 PM10/1/05
to TurboGears
I've been playing around with my data model, making changes to the
structure, dropping and recreating tables, and I've found it handy to
be able to run an initial data script in the context of the model
classes.

Something like:
turbogears-admin shell <filename to execute>

I've implemented this in mine - just by changing the last part of
command.Shell.run to be:

if len(sys.argv) == 2:
# execute the initial data file
datafile = sys.argv[1]
execfile(datafile, globals(), locals)
else:
import code
code.interact(local=locals)

And the initial data file would have something like:

fred = Author(name="fred", email="fr...@fred.com")
first = Item(title="First post!", slug='first_post', body='This is my
first blog entry', author=fred)

.. to create all your base data without requiring any trickiness or
imports to get the right context.

Does this seem like something other people could use? I guess more
thought could go into tying this into application deployment and such,
as well as whether that's the best way to indicate the data file to
use.

Cheers,
xtian

Kevin Dangoor

unread,
Oct 1, 2005, 9:16:32 PM10/1/05
to turbo...@googlegroups.com
On 10/1/05, xtian <wilbe...@gmail.com> wrote:
>
> I've been playing around with my data model, making changes to the
> structure, dropping and recreating tables, and I've found it handy to
> be able to run an initial data script in the context of the model
> classes.
>
> Something like:
> turbogears-admin shell <filename to execute>
>
> I've implemented this in mine - just by changing the last part of
> command.Shell.run to be:
>
> if len(sys.argv) == 2:
> # execute the initial data file
> datafile = sys.argv[1]
> execfile(datafile, globals(), locals)
> else:
> import code
> code.interact(local=locals)

I'd probably make it a new command like "exec" or "run" or something,
since it's not actually dropping you into the shell. Even better might
be an option for sql create to run this after creating the database.
(I assume you're using this to populate a fresh database while testing
things?)

Kevin

Krys Wilken

unread,
Oct 2, 2005, 9:10:47 AM10/2/05
to turbo...@googlegroups.com
Hi,

I did a similar script, but I use trickiness and imports to get the
context. :-)

I like you way better, so I vote +1 for this idea.

Krys

Krys Wilken

unread,
Oct 2, 2005, 9:22:43 AM10/2/05
to turbo...@googlegroups.com
I think both ideas are of value. An exec command for running scripts,
and a special module-level function in model.py that is run
automatically by sql create.

An alternative to a single module-level function would be a special
method on each model that is responsible for populating itself, perhaps
"post_create(self)" or something. Sql create could just call that
method of each model after all the tables have been created.

I don't personally have a use for the exec command if sql create can be
made to populate my tables, but I think someone somewhere might have a
use for it.

Just my $0.02.

Krys

Kevin Dangoor

unread,
Oct 2, 2005, 3:05:44 PM10/2/05
to turbo...@googlegroups.com
Given that I don't personally have a use for this right now, if
someone needs/wants these features, your best bet is to send me a
patch...

Kevin
--
Kevin Dangoor
Author of the Zesty News RSS newsreader

email: k...@blazingthings.com
company: http://www.BlazingThings.com
blog: http://www.BlueSkyOnMars.com

Krys Wilken

unread,
Oct 3, 2005, 6:15:14 AM10/3/05
to turbo...@googlegroups.com
I am certainly not opposed to that. If I get the time, I will give it a
shot. Unless someone else beats me to it. :-)

Krys

Ian Bicking

unread,
Oct 3, 2005, 11:17:51 AM10/3/05
to turbo...@googlegroups.com
xtian wrote:
> I've been playing around with my data model, making changes to the
> structure, dropping and recreating tables, and I've found it handy to
> be able to run an initial data script in the context of the model
> classes.

I've actually meant to include this functionality in sqlobject-admin, if
you are interested in making the change there. It would be a setting in
sqlobject.txt, maybe like "db_init_func = module:var", which would tell
SQLObject to run that function (probably with no arguments) after the
tables were created. A "db_init_test_func" might be a nice compliment,
which would run after db_init_func and insert test fixture data.

--
Ian Bicking / ia...@colorstudy.com / http://blog.ianbicking.org

Tim Lesher

unread,
Oct 4, 2005, 12:38:06 PM10/4/05
to turbo...@googlegroups.com
On 10/3/05, Ian Bicking <ia...@colorstudy.com> wrote:
> I've actually meant to include this functionality in sqlobject-admin, if
> you are interested in making the change there.

That would be excellent. The last time I used sqlobject (0.6.1) I had
to do some evil hacking to emulate both this functionality and
sqlobject-admin create.

Thanks.

--
Tim Lesher <tle...@gmail.com>

Fabian Neumann

unread,
Oct 7, 2005, 12:17:29 PM10/7/05
to TurboGears
Krys Wilken wrote:
> I think both ideas are of value. An exec command for running scripts,
> and a special module-level function in model.py that is run
> automatically by sql create.

I might like it, too. What do you think of this:

Index: turbogears/quickstart/projectname/model.py.source
===================================================================
--- turbogears/quickstart/projectname/model.py.source (Revision 43)
+++ turbogears/quickstart/projectname/model.py.source (Arbeitskopie)
@@ -6,3 +6,6 @@

# class YourDataClass(SQLObject):
# pass
+
+# def tg_init_database():
+# pass
Index: turbogears/command/__init__.py
===================================================================
--- turbogears/command/__init__.py (Revision 43)
+++ turbogears/command/__init__.py (Arbeitskopie)
@@ -104,6 +104,12 @@

from sqlobject.manager import command
command.the_runner.run(sys.argv)
+ if sqlobjcommand == "create":
+ mod = self.get_model()
+ if hasattr(mod, 'tg_init_database'):
+ print 'Filling database'
+ mod.tg_init_database()
+

def fix_egginfo(self, eggname):
print """


Two issues with that:
1. This behaviour may be unexpected by people who are familiar with
"sqlobject-admin create".
2. If you run "sql create" twice or more, those init values are doubled.

> An alternative to a single module-level function would be a special
> method on each model that is responsible for populating itself, perhaps
> "post_create(self)" or something. Sql create could just call that
> method of each model after all the tables have been created.

I don't think this granularity is useful, as you can only create all
models at once (I think).

Fabian

Krys Wilken

unread,
Oct 8, 2005, 1:39:54 PM10/8/05
to turbo...@googlegroups.com
This works for me. :-)

As for you point 1), if there is no tg_init_database, then the behaviour
is exactly as before and SQLObject users will not be confused. That is
to say, I have to do an explicit act to get the new behaviour and so I
will know what will happen.

As for point 2), I am thinking that a counterpart method like
tg_clear_database or something would be nice so that old data can be
torn down. And alternative would be to make your tg_init_database,
check for the existence of any data you are trying to insert.

Further a reset or rebuild method is a simple as tg_clear_database();
tg_init_database(). If that is useful.

And then there is the blue-sky-on-mars <wink> thinking that this could
be the base for model versioning with upgrade functions in each model to
that can migrate old data structures to new ones. I think this is a bit
far off, though. (Can you tell I have been played with Zope and
Twisted?) :-)

Krys
Reply all
Reply to author
Forward
0 new messages